github.com/whyrusleeping/gx@v0.14.3/README.md (about)

     1  ![gx logo](logo.jpeg)
     2  
     3  # gx
     4  > The language-agnostic, universal package manager
     5  
     6  [![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://protocol.ai) [![](https://img.shields.io/badge/freenode-%23gx-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs,%23gx)
     7  
     8  gx is a packaging tool built around the distributed, content addressed filesystem
     9  [IPFS](//github.com/ipfs/ipfs). It aims to be flexible, powerful and simple.
    10  
    11  gx is **Alpha Quality**. While not perfect, gx is reliable enough
    12  to manage dependencies in [go-ipfs](https://github.com/ipfs/go-ipfs/) and
    13  is ready for use by developers of all skill levels.
    14  
    15  ## Table of Contents
    16  - [Background](#background)
    17  - [Requirements](#requirements)
    18  - [Installation](#installation)
    19  - [Usage](#usage)
    20  - [Dependencies](#dependencies)
    21  - [Updating](#updating)
    22  - [Repos](#repos)
    23    - [Usage](#usage-1)
    24  - [Hooks](#hooks)
    25  - [The vendor directory](#the-vendor-directory)
    26  - [Using gx as a Go package manager](#using-gx-as-a-go-package-manager)
    27  - [Using gx as a Javascript package manager](#using-gx-as-a-javascrit-package-manager)
    28  - [Using gx as a package manager for language/environment X](#using-gx-as-a-package-manager-for-languageenvironment-x)
    29  - [Why is it called gx?](#why-is-it-called-gx)
    30  - [License](#license)
    31  
    32  ## Background
    33  
    34  gx was originally designed to handle dependencies in Go projects in a
    35  distributed fashion, and pulls ideas from other beloved package managers (like
    36  [npm](http://npmjs.org/)).
    37  
    38  gx was designed with the following major goals in mind:
    39  
    40  1. Be language/ecosystem agnostic by providing [git-like hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) for adding [new ecosystems](https://github.com/whyrusleeping/gx-go).
    41  2. Provide completely reproducible packages through content addressing.
    42  3. Use [a flexible, distributed storage backend](http://ipfs.io/).
    43  
    44  
    45  ## Requirements
    46  Users are encouraged to have a running [IPFS daemon](//github.com/ipfs/go-ipfs) of at least version 0.4.2 on their machines.
    47  If not present, gx will use the public gateway.
    48  If you wish to publish a package, a local running daemon is a hard requirement. If your IPFS repo is in a non-standard location, remember to set $IPFS_PATH. Alternatively, you can explicitly set $IPFS_API to $IPFS_API_IPADDR:$PORT.
    49  
    50  
    51  ## Installation
    52  
    53  ```
    54  $ (cd ~ && go get github.com/whyrusleeping/gx)
    55  ```
    56  
    57  This will download, build, and install a binary to `$GOPATH/bin`. To modify gx,
    58  just change the source in that directory, and run `go build`.
    59  
    60  ## Usage
    61  
    62  Creating and publishing new generic package:
    63  
    64  ```bash
    65  $ gx init
    66  $ gx publish
    67  ```
    68  
    69  This will output a 'package-hash' unique to the content of the
    70  package at the time of publishing. If someone downloads the package and
    71  republishes it, the *exact* same hash will be produced.
    72  
    73  ### package.json
    74  
    75  It should be noted that gx is meant to *work with* existing `package.json` files. If you are adding a package to gx that already has a `package.json` file in its root, gx will try and work with it. Any shared fields will have the same types, and any fields unique to gx will kept separate. 
    76  
    77  E.g. A single `package.json` file could be used to serve both gx and another packaging tool, such as npm. Since gx is **Alpha Quality** there may be some exceptions to the above statements, if you notice one, please file an issue.
    78  
    79  ## Installing a gx package
    80  If you've cloned down a gx package, simply run `gx install` or `gx i` to
    81  install it (and its dependencies).
    82  
    83  ## Dependencies
    84  To add a dependency of another package to your package, simply import it by its
    85  hash:
    86  
    87  ```bash
    88  $ gx import QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr
    89  ```
    90  
    91  This downloads the package specified by the hash into the `vendor` directory in your
    92  workspace. It also adds an entry referencing the package to the local `package.json`.
    93  
    94  Gx has a few nice tools to view and analyze dependencies. First off, the simple:
    95  
    96  ```bash
    97  $ gx deps
    98  go-log              QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52 1.2.0
    99  go-libp2p-peer      QmWXjJo15p4pzT7cayEwZi2sWgJqLnGDof6ZGMh9xBgU1p 2.0.4
   100  go-libp2p-peerstore QmYkwVGkwoPbMVQEbf6LonZg4SsCxGP3H7PBEtdNCNRyxD 1.2.5
   101  go-testutil         QmYpVUnnedgGrp6cX2pBii5HRQgcSr778FiKVe7o7nF5Z3 1.0.2
   102  go-ipfs-util        QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
   103  ```
   104  
   105  This just lists out the immediate dependencies of this package. To see
   106  dependencies of dependencies, use the `-r` option: (and optionally the `-s`
   107  option to sort them)
   108  
   109  ```bash
   110  $ gx deps -r -s
   111  go-base58           QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
   112  go-crypto           Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   113  go-datastore        QmbzuUusHqaLLoNTDEVLcSF6vZDHZDLPC7p4bztRvvkXxU 1.0.0
   114  go-ipfs-util        QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
   115  go-keyspace         QmUusaX99BZoELh7dmPgirqRQ1FAmMnmnBn3oiqDFGBUSc 1.0.0
   116  go-libp2p-crypto    QmVoi5es8D5fNHZDqoW6DgDAEPEV5hQp8GBz161vZXiwpQ 1.0.4
   117  go-libp2p-peer      QmWXjJo15p4pzT7cayEwZi2sWgJqLnGDof6ZGMh9xBgU1p 2.0.4
   118  go-libp2p-peerstore QmYkwVGkwoPbMVQEbf6LonZg4SsCxGP3H7PBEtdNCNRyxD 1.2.5
   119  go-log              QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52 1.2.0
   120  go-logging          QmQvJiADDe7JR4m968MwXobTCCzUqQkP87aRHe29MEBGHV 0.0.0
   121  go-multiaddr        QmYzDkkgAEmrcNzFCiYo6L1dTX4EAG1gZkbtdbd9trL4vd 0.0.0
   122  go-multiaddr-net    QmY83KqqnQ286ZWbV2x7ixpeemH3cBpk8R54egS619WYff 1.3.0
   123  go-multihash        QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
   124  go-net              QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt 0.0.0
   125  go-testutil         QmYpVUnnedgGrp6cX2pBii5HRQgcSr778FiKVe7o7nF5Z3 1.0.2
   126  go-text             Qmaau1d1WjnQdTYfRYfFVsCS97cgD8ATyrKuNoEfexL7JZ 0.0.0
   127  go.uuid             QmcyaFHbyiZfoX5GTpcqqCPYmbjYNAhRDekXSJPFHdYNSV 1.0.0
   128  gogo-protobuf       QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV 0.0.0
   129  goprocess           QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP 1.0.0
   130  mafmt               QmeLQ13LftT9XhNn22piZc3GP56fGqhijuL5Y8KdUaRn1g 1.1.1
   131  ```
   132  
   133  That's pretty useful, I now know the full set of packages my package depends on.
   134  But what's difficult now is being able to tell what is imported where. To
   135  address that, gx has a `--tree` option:
   136  
   137  ```bash
   138  $ gx deps --tree
   139  ├─ go-base58          QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
   140  ├─ go-multihash       QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
   141  │  ├─ go-base58       QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
   142  │  └─ go-crypto       Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   143  ├─ go-ipfs-util       QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
   144  │  ├─ go-base58       QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
   145  │  └─ go-multihash    QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
   146  │     ├─ go-base58    QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
   147  │     └─ go-crypto    Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   148  ├─ go-log             QmNQynaz7qfriSUJkiEZUrm2Wen1u3Kj9goZzWtrPyu7XR 1.1.2
   149  │  ├─ randbo          QmYvsG72GsfLgUeSojXArjnU6L4Wmwk7wuAxtNLuyXcc1T 0.0.0
   150  │  ├─ go-net          QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt 0.0.0
   151  │  │  ├─ go-text      Qmaau1d1WjnQdTYfRYfFVsCS97cgD8ATyrKuNoEfexL7JZ 0.0.0
   152  │  │  └─ go-crypto    Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   153  │  └─ go-logging      QmQvJiADDe7JR4m968MwXobTCCzUqQkP87aRHe29MEBGHV 0.0.0
   154  └─ go-libp2p-crypto   QmUEUu1CM8bxBJxc3ZLojAi8evhTr4byQogWstABet79oY 1.0.2
   155     ├─ gogo-protobuf   QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV 0.0.0
   156     ├─ go-log          Qmazh5oNUVsDZTs2g59rq8aYQqwpss8tcUWQzor5sCCEuH 0.0.0
   157     │  ├─ go.uuid      QmPC2dW6jyNzzBKYuHLBhxzfWaUSkyC9qaGMz7ciytRSFM 0.0.0
   158     │  ├─ go-logging   QmQvJiADDe7JR4m968MwXobTCCzUqQkP87aRHe29MEBGHV 0.0.0
   159     │  ├─ go-net       QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt 0.0.0
   160     │  │  ├─ go-text   Qmaau1d1WjnQdTYfRYfFVsCS97cgD8ATyrKuNoEfexL7JZ 0.0.0
   161     │  │  └─ go-crypto Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   162     │  └─ randbo       QmYvsG72GsfLgUeSojXArjnU6L4Wmwk7wuAxtNLuyXcc1T 0.0.0
   163     ├─ go-ipfs-util    QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
   164     │  ├─ go-base58    QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
   165     │  └─ go-multihash QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
   166     │     ├─ go-base58 QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
   167     │     └─ go-crypto Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   168     └─ go-msgio        QmRQhVisS8dmPbjBUthVkenn81pBxrx1GxE281csJhm2vL 0.0.0
   169        └─ go-randbuf   QmYNGtJHgaGZkpzq8yG6Wxqm6EQTKqgpBfnyyGBKbZeDUi 0.0.0
   170  ```
   171  
   172  Now you can see the *entire* tree of dependencies for this project. Although,
   173  for larger projects, this will get messy. If you're just interested in the
   174  dependency tree of a single package, you can use the `--highlight` option
   175  to filter the trees printing:
   176  
   177  ```bash
   178  $ gx deps --tree --highlight=go-crypto
   179  ├─ go-multihash       QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
   180  │  └─ go-crypto       Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   181  ├─ go-ipfs-util       QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
   182  │  └─ go-multihash    QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
   183  │     └─ go-crypto    Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   184  ├─ go-log             QmNQynaz7qfriSUJkiEZUrm2Wen1u3Kj9goZzWtrPyu7XR 1.1.2
   185  │  └─ go-net          QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt 0.0.0
   186  │     └─ go-crypto    Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   187  └─ go-libp2p-crypto   QmUEUu1CM8bxBJxc3ZLojAi8evhTr4byQogWstABet79oY 1.0.2
   188     ├─ go-log          Qmazh5oNUVsDZTs2g59rq8aYQqwpss8tcUWQzor5sCCEuH 0.0.0
   189     │  └─ go-net       QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt 0.0.0
   190     │     └─ go-crypto Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   191     └─ go-ipfs-util    QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
   192        └─ go-multihash QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
   193           └─ go-crypto Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   194  ```
   195  
   196  This tree is a subset of the previous one, filtered to only show leaves that
   197  end in the selected package.
   198  
   199  The gx deps command also has two other smaller subcommands, `dupes` and
   200  `stats`. `gx deps dupes` will print out packages that are imported multiple
   201  times with the same name, but different hashes. This is useful to see if
   202  different versions of the same package have been imported in different places
   203  in the dependency tree. Allowing the user to more easily address the
   204  discrepancy. `gx deps stats` will output the total number of packages imported
   205  (total and unique) as well as the average depth of imports in the tree. This
   206  gives you a rough idea of the complexity of your package.
   207  
   208  ### The gx dependency graph manifesto
   209  I firmly believe that packages are better when:
   210  
   211  #### 1. The depth of the dependency tree is minimized.
   212  This means restructuring your code in such a way that flattens (and perhaps
   213  widens as a consequence) the tree. For example, in Go, this often times means
   214  making an interface its own package, and implementations into their own
   215  separate packages. The benefits here are that flatter trees are far easier to
   216  update. For every package deep a dependency is, you have to update, test,
   217  commit, review and merge another package. That's a lot of work, and also a lot
   218  of extra room for problems to sneak in.
   219  
   220  #### 2. The width of the tree is minimized, but not at the cost of increasing depth.
   221  This should be fairly common sense, but striving to import packages only where
   222  they are actually needed helps to improve code quality. Imagine having a helper
   223  function in one package, simply because it's convenient to have it there, that
   224  depends on a bunch of other imports from elsewhere in the tree. Sure it's nice,
   225  and doesn't actually increase the 'total' number of packages you depend on. But
   226  now you've created an extra batch of work for you to do any time any of these
   227  are updated, and you also now force anyone who wants to import the package with
   228  your helper function to also import all those other dependencies.
   229  
   230  Adhering to the above two rules should (I'm very open to discussion on this)
   231  improve overall code quality, and make your codebase far easier to navigate and
   232  work on.
   233  
   234  ## Updating
   235  Updating packages in gx is simple:
   236  
   237  ```bash
   238  $ gx update mypkg QmbH7fpAV1FgMp6J7GZXUV6rj6Lck5tDix9JJGBSjFPgUd
   239  ```
   240  
   241  This looks into your `package.json` for a dependency named `mypkg` and replaces
   242  its hash reference with the one given.
   243  
   244  Alternatively, you can just specify the hash you want to update to:
   245  
   246  ```bash
   247  $ gx update QmbH7fpAV1FgMp6J7GZXUV6rj6Lck5tDix9JJGBSjFPgUd
   248  ```
   249  
   250  Doing it this way will pull down the package, check its name, and then update
   251  that dependency.
   252  
   253  Note that by default, this will not touch your code at all, so any references
   254  to that hash you have in your code will need to be updated. If you have a
   255  language tool (e.g. `gx-go`) installed, and it has a `post-update` hook,
   256  references to the given package should be updated correctly. If not, you may
   257  have to run sed over the package to update everything. The bright side of that
   258  is that you are very unlikely to have those hashes sitting around for any other
   259  reason so a global find-replace should be just fine.
   260  
   261  ## Publishing and Releasing
   262  Gx by default will not let you publish a package twice if you haven't updated
   263  its version. To get around this, you can pass the `-f` flag. Though this is not
   264  recommended, it's still perfectly possible to do.
   265  
   266  To update the version easily, use the `gx version` subcommand. You can either set the version manually:
   267  
   268  ```bash
   269  $ gx version 5.11.4
   270  ```
   271  
   272  Or just do a 'version bump':
   273  
   274  ```bash
   275  $ gx version patch
   276  updated version to: 5.11.5
   277  $ gx version minor
   278  updated version to: 5.12.0
   279  $ gx version major
   280  updated version to: 6.0.0
   281  ```
   282  
   283  Most of the time, your process will look something like:
   284  
   285  ```bash
   286  $ gx version minor
   287  updated version to: 6.1.0
   288  $ gx publish
   289  package whys-awesome-package published with hash: QmaoaEi6uNMuuXKeYcXM3gGUEQLzbDWGcFUdd3y49crtZK
   290  $ git commit -a -m "gx publish 6.1.0"
   291  [master 5c4d36c] gx publish 6.1.0
   292   2 files changed, 3 insertions(+), 2 deletions(-)
   293  ```
   294  
   295  The `release` subcommand can be used to automate the above process. `gx release <version>`
   296  will do a version update (using the same inputs as the normal
   297  `version` command), run a `gx publish`, and then execute whatever you have set
   298  in your `package.json` as your `releaseCmd`. To get the above git commit flow,
   299  you can set it to: `git commit -a -m \"gx publish $VERSION\"` and gx will
   300  replace `$VERSION` with the newly changed version before executing the git
   301  commit.
   302  
   303  ### Ignoring files from a publish
   304  You can use a `.gxignore` file to make gx ignore certain files during a publish.
   305  This has the same behaviour as a `.gitignore`.
   306  
   307  Gx also respects a `.gitignore` file if present, and will not publish any file
   308  excluded by it.
   309  
   310  
   311  ## Repos
   312  gx supports named packages via user configured repositories. A repository is
   313  simply an ipfs object whose links name package hashes. You can add a repository
   314  as either an ipns or ipfs path.
   315  
   316  ### Usage
   317  
   318  Add a new repo
   319  ```bash
   320  $ gx repo add myrepo /ipns/QmPupmUqXHBxikXxuptYECKaq8tpGNDSetx1Ed44irmew3
   321  ```
   322  
   323  List configured repos
   324  ```bash
   325  $ gx repo list
   326  myrepo       /ipns/QmPupmUqXHBxikXxuptYECKaq8tpGNDSetx1Ed44irmew3
   327  ```
   328  
   329  List packages in a given repo
   330  ```bash
   331  $ gx repo list myrepo
   332  events      QmeJjwRaGJfx7j6LkPLjyPfzcD2UHHkKehDPkmizqSpcHT
   333  smalltree   QmRgTZA6jGi49ipQxorkmC75d3pLe69N6MZBKfQaN6grGY
   334  stump       QmebiJS1saSNEPAfr9AWoExvpfGoEK4QCtdLKCK4z6Qw7U
   335  ```
   336  
   337  Import a package from a repo:
   338  ```bash
   339  $ gx repo import events
   340  ```
   341  
   342  ## Hooks
   343  gx supports a wide array of use cases by having sane defaults that are
   344  extensible based on the scenario the user is in. To this end, gx has hooks that
   345  get called during certain operations.
   346  
   347  These hooks are language specific, and gx will attempt to make calls to a
   348  helper binary matching your language to execute the hooks. For example, when
   349  writing go, gx calls `gx-go hook <hookname> <args>` for any given hook.
   350  
   351  Currently available hooks are:
   352  
   353  - `post-import`
   354    - called after a new package is imported and its info written to package.json.
   355    - takes the hash of the newly imported package as an argument.
   356  - `post-init`
   357    - called after a new package is initialized.
   358    - takes an optional argument of the directory of the newly init'ed package.
   359  - `pre-publish`
   360    - called during `gx publish` before the package is bundled up and added to ipfs.
   361    - currently takes no arguments.
   362  - `post-publish`
   363    - called during `gx publish` after the package has been added to ipfs.
   364    - takes the hash of the newly published package as an argument.
   365  - `post-update`
   366    - called during `gx update` after a dependency has been updated.
   367    - takes the old package ref and the new hash as arguments.
   368  - `post-install`
   369    - called after a new package is downloaded, during install and import.
   370    - takes the path to the new package as an argument.
   371  - `install-path`
   372    - called during package installs and imports.
   373    - sets the location for gx to install packages to.
   374  
   375  ## Package directories
   376  
   377  Gx by default will install packages 'globally' in the global install location
   378  for your given project type.  Global gx packages are shared across all packages
   379  that depend on them.  The location of this directory can be changed if desired. Add a hook
   380  to your environments extension tool named `install-path` (see above) and gx
   381  will use that path instead. If your language does not set a global install
   382  path, gx will fallback to installing locally as the default.  This means that
   383  it will create a folder in the current directory named `vendor` and install
   384  things to it.
   385  
   386  When running `gx install` in the directory of your package, gx will recursively
   387  fetch all of the dependencies specified in the `package.json` and save them to
   388  the install path specified.
   389  
   390  Gx supports both local and global installation paths. Since the default is
   391  global, to install locally, use `--local` or `--global=false`.  The global flag
   392  is passed to the `install-path` hook for your extension code to use in its
   393  logic.
   394  
   395  ## Using gx as a Go package manager
   396  
   397  If you want (like me) to use gx as a package manager for go, it's pretty easy.
   398  You will need the gx go extensions before starting your project:
   399  ```
   400  $ go get -u github.com/whyrusleeping/gx-go
   401  ```
   402  
   403  Once that's installed, use gx like normal to import dependencies.
   404  You can import code from the vendor directory using:
   405  ```go
   406  import "gx/ipfs/<hash>/packagename"
   407  ```
   408  
   409  for example, if i have a package foobar, you can import with gx it like so:
   410  ```bash
   411  $ gx import QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa
   412  ```
   413  
   414  And then in your go code, you can use it with:
   415  ```go
   416  import "gx/ipfs/QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa/foobar"
   417  ```
   418  
   419  Then simply set the environment variable `GO15VENDOREXPERIMENT` to `1` and run
   420  `go build` or `go install` like you normally would. Alternatively, install
   421  your dependencies globally (`gx install --global`) and you can leave off the
   422  environment variable part.
   423  
   424  See [the gx-go repo](https://github.com/whyrusleeping/gx-go) for more details.
   425  
   426  ## Using gx as a Javascript package manager
   427  
   428  Please take a look at [gx-js](https://github.com/sterpe/gx-js).
   429  
   430  ## Using gx as a package manager for language/environment X
   431  
   432  If you want to use gx with a big bunch of repositories/packages please
   433  take a look at [gx-workspace](https://github.com/ipfs/gx-workspace).
   434  
   435  If you want to extend gx to work with any other language or environment, you
   436  can implement the relevant hooks in a binary named `gx-X` where the 'X' is the
   437  name of your environment. After that, any package whose language is set to 'X'
   438  will call out to that tools hooks during normal `gx` operations. For example, a
   439  'go' package would call `gx-go hook pre-publish` during a `gx publish`
   440  invocation before the package is actually published.  For more information on
   441  hooks, check out the hooks section above.
   442  
   443  See also the `examples` directory.
   444  
   445  ## Why is it called gx?
   446  
   447  No reason. "gx" stands for nothing.
   448  
   449  ## Getting Involved
   450  
   451  If you're interested in gx, please stop by #gx and #ipfs on freenode irc!
   452  
   453  ## License
   454  
   455  MIT. Jeromy Johnson.