Giter VIP home page Giter VIP logo

envify's Introduction

envify Build Status stable

Selectively replace Node-style environment variables with plain strings. Available as a standalone CLI tool and a Browserify v2 transform.

Works best in combination with uglifyify.

Installation

If you're using the module with Browserify:

npm install envify browserify

Or, for the CLI:

sudo npm install -g envify

Usage

envify will replace your environment variable checks with ordinary strings - only the variables you use will be included, so you don't have to worry about, say, AWS_SECRET_KEY leaking through either. Take this example script:

if (process.env.NODE_ENV === "development") {
  console.log('development only')
}

After running it through envify with NODE_ENV set to production, you'll get this:

if ("production" === "development") {
  console.log('development only')
}

By running this through a good minifier (e.g. UglifyJS2), the above code would be stripped out completely.

However, if you bundled the same script with NODE_ENV set to development:

if ("development" === "development") {
  console.log('development only')
}

The if statement will evaluate to true, so the code won't be removed.

CLI Usage

With browserify:

browserify index.js -t envify > bundle.js

Or standalone:

envify index.js > bundle.js

You can also specify additional custom environment variables using browserify's subarg syntax, which is available in versions 3.25.0 and above:

browserify index.js -t [ envify --NODE_ENV development ] > bundle.js
browserify index.js -t [ envify --NODE_ENV production  ] > bundle.js

Module Usage

require('envify')

Returns a transform stream that updates based on the Node process' process.env object.

require('envify/custom')([environment])

If you want to stay away from your environment variables, you can supply your own object to use in its place:

var browserify = require('browserify')
  , envify = require('envify/custom')
  , fs = require('fs')

var b = browserify('main.js')
  , output = fs.createWriteStream('bundle.js')

b.transform(envify({
  NODE_ENV: 'development'
}))
b.bundle().pipe(output)

Purging process.env

By default, environment variables that are not defined will be left untouched. This is because in some cases, you might want to run an envify transform over your source more than once, and removing these values would make that impossible.

However, if any references to process.env are remaining after transforming your source with envify, browserify will automatically insert its shim for Node's process object, which will increase the size of your bundle. This weighs in at around 2KB, so if you're trying to be conservative with your bundle size you can "purge" these remaining variables such that any missing ones are simply replaced with undefined.

To do so through the command-line, simply use the subarg syntax and include purge after envify, e.g.:

browserify index.js -t [ envify purge --NODE_ENV development ]

Or if you're using the module API, you can pass _: "purge" into your arguments like so:

b.transform(envify({
    _: 'purge'
  , NODE_ENV: 'development'
}))

Contributors

envify's People

Contributors

andreypopp avatar ariya avatar benjamn avatar bjoerge avatar edi9999 avatar hughsk avatar jupl avatar monsanto avatar timwis avatar yoshuawuyts avatar zag2art avatar zertosh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

envify's Issues

undefined values?

I've been trying to use envify and it works great for the environment variables I actually put in.

However, any environment variables I fail to put in are left untouched. It would be nice if they were replaces with undefined, as the code very often depends on that behavior.

In particular I'm dealing with something like this

module.exports = {
  hostname: process.env.HOSTNAME || 'http://example.com'
};

right now if the HOSTNAME environment variable is not set this code is left untouched. It would be nice if this was transformed to:

module.exports = {
  hostname: undefined || 'http://example.com'
};

as that is the correct behavior. Thanks.

Unable to run from node_modules/.bin folder

Hello, I can't run envify from node_modules/.bin folder. Throwing this error. Can you please take a look what might be wrong

Error: Unexpected object exported by the "/home/user/Code/frontend/node_modules/.bin/envify" package. Expected a transform function.
    at nr (/home/user/Code/frontend/node_modules/module-deps/index.js:291:27)
    at onfile (/home/user/Code/frontend/node_modules/resolve/lib/async.js:51:21)
    at onex (/home/user/Code/frontend/node_modules/resolve/lib/async.js:93:22)
    at /home/user/Code/frontend/node_modules/resolve/lib/async.js:24:18
    at FSReqWrap.oncomplete (fs.js:123:15)

Here is how to reproduce

npm init -y
npm i --save envify browserify
touch app.js
./node_modules/.bin/browserify app.js -t ./node_modules/.bin/envify > bundle.js

Allow specifying extensions

Right now envify processes files of all extensions, except for .json.

I'm in a situation where I'm requiring files of different extensions (.html to load template strings, .tag for RiotJS tag files), and I need envify to apply only to .js, and ignore those files.

I think this could be added in a pretty-backwards-compatible way:

If the env property is not an object, the current behavior is assumed:

envify({
  _: 'purge',
  BUTTS: 'YES',
  env: 'PRODUCTION'
})

If the env property is an object, its properties are used as the environment variables, and the rest of the top-level object is used for options like purge and extensions:

envify({
  purge: true,
  extensions: ['.js', '.mjs'],
  env: {
    BUTTS: 'YES',
    env: 'PRODUCTION'
  }
})

What do you think? Would you take a pull request implementing this change? Would you prefer a different implementation, or would you rather not support different extensions?

Use without process env

There is a way to use without including the object process.env (like webpack define plugin work)?

So I can write something like this:

if( PRODUCTION ) {  }

Error using transform

I'm probably doing something wrong, whenever I call envify my cli throws. Could you help me out?

task.js:

/**
 * Compile JS
 */

gulp.task('modules', function() {
  browserify(__dirname + '/client/modules/index/index.js')
    .transform(envify({NODE_ENV: process.env.NODE_ENV}))
    .transform({global: true}, 'uglifyify')
    .bundle({debug: true})
    .pipe(source('build.js'))
    .pipe(gulp.dest(__dirname + '/build/'));
});

cli error:

❯ versity build
/home/yoshua/Code/versity
[17:40:14] Starting 'styles'...
[17:40:14] Finished 'styles' after 16 ms
[17:40:14] Starting 'modules'...
[17:40:14] Finished 'modules' after 9.79 ms
[17:40:14] Starting 'assets'...
[17:40:14] Finished 'assets' after 785 μs
[17:40:14] Starting 'default'...
[17:40:14] Finished 'default' after 52 μs
/home/yoshua/Code/versity/node_modules/browserify/index.js:372
        return function (file) { return t.call(this, file, opts) };
                                          ^
TypeError: Object #<Stream> has no method 'call'
    at /home/yoshua/Code/versity/node_modules/browserify/index.js:372:43
    at makeTransform (/home/yoshua/Code/versity/node_modules/browserify/node_modules/module-deps/index.js:209:21)
    at /home/yoshua/Code/versity/node_modules/browserify/node_modules/module-deps/index.js:186:9
    at Deps.getTransforms (/home/yoshua/Code/versity/node_modules/browserify/node_modules/module-deps/index.js:191:7)
    at Deps.readFile (/home/yoshua/Code/versity/node_modules/browserify/node_modules/module-deps/index.js:164:25)
    at /home/yoshua/Code/versity/node_modules/browserify/node_modules/module-deps/index.js:280:14
    at onresolve (/home/yoshua/Code/versity/node_modules/browserify/node_modules/module-deps/index.js:150:14)
    at /home/yoshua/Code/versity/node_modules/browserify/index.js:737:13
    at next (/home/yoshua/Code/versity/node_modules/browserify/index.js:781:17)
    at /home/yoshua/Code/versity/node_modules/browserify/index.js:785:33

Configure envify in package.json

Hello,

Thanks for a great lib. Any idea how to pass the "purge" option to envify in package.json config? For example, I thought this would work:

"browserify": {
  "transform": [["envify", "purge"]]
}

Or this:

"browserify": {
  "transform": [["envify", { "purge": true }]]
}

But neither seem to work. Any suggestions?

Thanks!

How to configure it with karma.conf?

browserify: {
            debug: true,
            transform: [
                'babelify',
                ['envify', 'browserify-istanbul', { instrumenter: require('isparta') }]
            ]
        }

I tried somenthing like this but i got an error:
node_modules/karma-browserify/node_modules/browserify/index.js:313 opts._flags = '_flags' in opts ? opts._flags : self._options;Cannot use 'in' operator to search for '_flags' in envify

am i missing some configuration?

Including envify as a transform causes browserify to throw an error

This is odd.

If I do:

browserify -t envify entrypoint.js

it will work.

However, if I do:
browserify('entrypoint.js').transform(require('envify')()).bundle()

browserify will crash with:

Unable to build /home/user/scripto2/src/static/js/entrypoint.js path must be a string Error: path must be a string
        at /home/user/scripto2/node_modules/browserify/node_modules/resolve/lib/async.js:16:16
        at doNTCallback0 (node.js:407:9)
        at process._tickDomainCallback (node.js:377:13) { err:
       { [Error: path must be a string]
         stream:
          Labeled {
            _readableState: [Object],
            readable: true,
            domain: null,
            _events: [Object],
            _eventsCount: 4,
            _maxListeners: undefined,
            _writableState: [Object],
            writable: true,
            allowHalfOpen: true,
            _options: [Object],
            _wrapOptions: [Object],
            _streams: [Object],
            length: 1,
            label: 'deps' } } }

If I remove the .transform call everything works correctly.

browserify 10.2.6 (as well as 11.0.1)
envify 3.4.0

I've created a simple test case here: https://github.com/toddself/envify-example

if you do node bundle.js you'll see the error. if you remove the call to .transform it'll work. (it doesn't matter if you put envify in the .transform call or in the transform keys in package.json -- they both fail). However, if you do node_modules/.bin/browserify -t envify entrypoint.js it'll work...

Using envify in laravel/elixir project

I have this in my gulpfile.js

elixir(function(mix) {
   mix.browserify(['app.jsx'], 'public/js/app.js');
});

How can I add envify so I could use env variables in my app.jsx ?
Thanks

Package configurations taking priority over environment variables

I have a use case where I would like environment variable definitions to override properties to envify, the default values of which would be contained in the package.json file. Something like this:

  "scripts" {
    "build-yes": "MY_VAR=YES browserify .",
    "build": "browserify ."
  },
  "browserify": {
    "transform": [
      "babelify",
      "browserify-shim",
      [
        "envify",
        {
          "MY_VAR": "NO"
        }
      ]
    ]
  }

Unfortunately, the re-definition derived from the script "build-yes" does not take place. Removing the definition of "MY_VAR":"NO" in the package is the only way for "MY_VAR=YES" to reach the transform. Is this the desired behaviour? Could these priorities be reconsidered?

/custom not working

I've trouble getting the envify/custom version working. The following code bundles without errors, but still contains process.env.NODE_ENV. Nothing has been replaced:

const envify = require('envify/custom')

/* browserify() */.transform(envify({

	NODE_ENV: 'production'

}))/* .bundle() */

The normal module however works fine.

const envify = require('envify')

process.env.NODE_ENV = 'production'

/* browserify() */.transform(envify)/* .bundle() */

Is there a difference between setting process.env.NODE_ENV = 'production' and passing NODE_ENV: 'production' to the custom module?


Node v6.7.0
envify v4.0.0

All tests are passing on my setup.

Envify options in gulp

I've run across an issue in transform declaration syntax. The following, using a method, does not work for setting the NODE_ENV:

var b = browserify({
    'cache': {},
    'packageCache': {},
    'fullPaths': true,
    'entries': [paths.jsPath + (argv.path === 'background' ? paths.background : paths.main) + '.js'],
    'noParse': ['react.js', 'jquery.js', 'pdf.combined.js'],
    'transform': [reactify]
  })
  .transform('brfs', { global: true })
  .transform(envify({
    global: true,
    _: 'purge',
    NODE_ENV: 'production'
  }))

However, the following does, calling envify in the transform array:

var b = browserify({
    'cache': {},
    'packageCache': {},
    'fullPaths': true,
    'entries': [paths.jsPath + (argv.path === 'background' ? paths.background : paths.main) + '.js'],
    'noParse': ['react.js', 'jquery.js', 'pdf.combined.js'],
    'transform': [[reactify], ['envify', {'global': true, '_': 'purge', NODE_ENV: 'production'}]]
  })
  .transform('brfs', { global: true })

I don't know the difference, or why one works and not the other. Calling NODE_ENV=production gulp also works, regardless of declaration of envify in the gulp file.

It's not working

I'm using Browserify, and when I minified JS code with using React and Redux, it saids:

Warning: It looks like you're using a minified copy of the development build of React. When deploying React apps to production, make sure to use the production build which skips development warnings and is faster. See https://fb.me/react-minification for more details.

You are currently using minified code outside of NODE_ENV === 'production'. This means that you are running a slower development build of Redux. You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) to ensure you have the correct code for your production build.

So I added envify and used like this:

const vendors = [
	'connected-react-router', 
	'history', 
	'immutable', 
	'isomorphic-fetch', 
	'moment', 
	'react', 
	'react-dom', 
	'react-if', 
	'react-motion-ui-pack', 
	'react-redux', 
	'react-router', 
	'redux'
];
const isProduction = config.isProduction;

function buildVendor() {
	const b = persistify({ debug: !isProduction });

	vendors.forEach(vendor => {
		b.require(vendor);
	});

	if(isProduction) {
		console.log('envify');
		b.transform(envify({
			NODE_ENV: 'production'
		}));
	}

	let stream =  b.bundle()
	.on('error', swallowError)
	.pipe(source('vendor.js'))
	.pipe(buffer())
	.pipe(rename('vendor.js'));

	if(isProduction) {
		stream.pipe(uglify());
	}

	return stream.pipe(gulp.dest(`${DIST}/js`));
}

You can see that when it's production mode, it calls envify, also I printed "envify" on the console when it runs.

After run the browserify(with gulp), it saids 'envify':

[ec2-user@ip-172-31-22-2 modernator-2]$ gulp build --all
[11:58:05] Using gulpfile ~/modernator-2/gulpfile.js
[11:58:05] Starting 'build'...
envify    <-- ENVIFY CALLED
[11:58:05] Moving external resources done. (Time elapsed 27ms.)
[11:58:05] Building HTML done. (Time elapsed 431ms.)
[11:58:05] Compiling SCSS done. (Time elapsed 99ms.)
[11:58:06] 826520 bytes written (1.12 seconds)
[11:58:16] Moving images done. (Time elapsed 11007ms.)
[11:58:16] Finished 'build' after 11 s

But still same errors on the webbrowser's console:

Warning: It looks like you're using a minified copy of the development build of React. When deploying React apps to production, make sure to use the production build which skips development warnings and is faster. See https://fb.me/react-minification for more details.

You are currently using minified code outside of NODE_ENV === 'production'. This means that you are running a slower development build of Redux. You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) to ensure you have the correct code for your production build.

I'm running multiple node services on single server, so I can't set NODE_ENV to production, because some of them are still in development mode. Is there a something that I missed? Why it won't worked at all?

I'm using

  • node v.6.9.5
  • envify v4.0.0
  • browserify v7.3.0

process.env.npm_package_version not replaced

This is something between a question and an issue, since I am not sure how it should work.

I have in the code

var version = process.env.npm_package_version

and I would expect envify to replace this with the npm package version. But it doesn't.

using envify purge option in package.json browserify field

It took me a while to get the envify purge option right inside the package.json.

I'm just posting it here for reference.

  "browserify": {
    "transform": [
      ["brfs"],
      ["envify", {"_": "purge"}]
    ]
  },

note: brfs is not needed, it's just showing how to add several transforms.

readme typo

do you really mean this?

if ("production" === "development") {
  console.log('development only')
}

Improve default behavior

I ran into #7 again today, which made me wonder if we might improve the default behavior or envify.

Instead of having to choose between require('envify') and require('envify/custom') this behavior might be more intuitive.

var envify = require('envify');

// detects the process.env.NODE_ENV variable
browserify()
  .transform(envify())

// manually override the environment
browserify()
   .transform(envify({env: 'custom'});

Let me know what you think, if you approve I'll PR the changes.

Not replacing library environment variables

I'm trying to use this transform on a project, but the transform doesn't seem to be replacing the environment variables within a library (specifically React, but I don't know if that makes a difference here).

To reproduce:

mkdir eg
cd eg

npm install -g browserify
npm install react envify
echo "require('react');" > file.js

# This ought to return no results, but it does
browserify -t [ envify --NODE_ENV production ] file.js | grep NODE_ENV

Transform does not seem to take effect when being ran as part of a Docker build

My app is Containerized inside of Docker. I am using gulp to build my client side app. In order to ensure that the client bundle is ready to go when the container starts I run my gulp build via the Dockerfile.

For some reason when the build run via the Docker file, everything builds just fine, but envify has no impact on the build. None of the process.env references are replaced. However, if I open a shell into the container after it has started, and then re-run gulp build, envify takes effect.

I have analized the bundles created before and after the second run of gulp build, and browserify is definitely running and other transforms are executed in both cases. It just seems that envify is not running when triggered by the Docker build.

Any ideas what could be causing this? Does envify depend on some kind of shell state (since it works when I run via a shell command, but not when the run happens automatically via the Docker build)?

Error if environment variable doesn't exist

I don't know if this is intended, but say the environment variable NODE_ENV is not defined in my shell, then the transform leaves process.env.NODE_ENV as-is, which raises an error because process is not defined.

Maybe replace process.env.NODE_ENV with undefined instead?

Could envify be used to enable dynamic-ish require() statements with browserify?

Just following a thread here, not sure if it's possible or not.

As noted in browserify/browserify#377 browserify uses static analysis to figure out what to build.

I'm working on a network of sites where we want to include different config for each property, where the property is identified by an environment variable.

That means we have a config file that looks like this:

if (process.env.SITE_KEY === 'site1') {
    module.exports = require('./site1');
} else if (process.env.SITE_KEY === 'site2') {
    module.exports = require('./site2');
}

Any other module that wants to know something in the site config requires this one.

The problem is that all site configs are bundled into each site's build, even though only the active one is used. Not really a huge issue, but it's not a clean solution either.

It seems like it might be possible to hook envify into the browserify pipeline in a way that replaces environment variables before require statements are evaluated, which would allow the following:

module.exports = require('./' + process.env.SITE_KEY);

If we could rewrite that with envify before browserify goes looking for require statements, it would see:

module.exports = require('./site1');

Any ideas on whether that's possible / feasible? Or do you know of any other ways to achieve this? I went looking but didn't find anything.

(Hopefully) remove esprima-fb dependency

I've submitted this PR facebookarchive/jstransform#29. If that gets merged then it's possible to simplify the dependencies so that there isn't a case of multiple esprima-fb versions as described in the PR's comment.

I'd be more than happy to submit a PR that basically does this when the time is right:

diff --git a/package.json b/package.json
index fcfc0a6a..a01af729 100644
--- a/package.json
+++ b/package.json
@@ -21,8 +21,7 @@
   "dependencies": {
     "xtend": "~2.1.2",
     "through": "~2.3.4",
-    "esprima-fb": "^4001.3001.0-dev-harmony-fb",
-    "jstransform": "^6.1.0"
+    "jstransform": "WHATEVER_VERSION_IS_NEXT"
   },
   "keywords": [
     "environment",
diff --git a/visitors.js b/visitors.js
index 48cb1548..e93848f6 100644
--- a/visitors.js
+++ b/visitors.js
@@ -1,5 +1,5 @@
-var Syntax = require('esprima-fb').Syntax
 var utils = require('jstransform/src/utils')
+var Syntax = utils.Syntax

 function create(envs) {

Request to add license to repo

Greetings - I noticed that the package.json file states a license of MIT, yet no license file was found in the repository. To make it clearer and easier for the downstream users to identify the license, would you mind adding an MIT license (https://opensource.org/licenses/MIT) to the source tree? Let me know if you would like me to make a pull request with the license text.

Thanks,
Gary

doesn't seem to work with symlinked files

So i have some files symlinked into node_modules more on it here.

That way i can require('myServices/service'); instead of require('../../../myServices/service')

Unfortunately if i have something like process.env.MY_VAR inside that file (service.js) it will not be transformed.

Any thoughts or suggestions?

Can't get environment variables to replace

This is not an issue as much as a support question. But I couldn't find another forum.

My environment variables are not being replaced when running the following in my universal reactapp:

const envify = require('envify/custom');

// function declarations etc
  browserify()
    .transform(
      babelify.configure({
        ignore: [/(bower_components)|(node_modules)/]
      })
    )
    .transform(envify(process.env))
    .bundle()
    .on('error', handleError)
    .pipe(source('app.js'))
    .pipe(buffer())
    .pipe(gulpif(globalSettings.production, stripDebug()))
    .pipe(gulpif(globalSettings.production, uglify()))
    .pipe(gulp.dest(taskSettings.scripts.dest));

It works locally, but not in my staging environment where the server shows the correct stuff based on env, but is then being replaced by client hydration.

I've described my problem in more detail in this StackOverflow question: https://stackoverflow.com/questions/55594832/envify-not-replacing-my-environment-variables

Grateful for any help!

Can't install envify in a local environment

npm ERR! peerinvalid The package envify does not satisfy its siblings' peerDependencies requirements!

Happens when I am trying out the flux example
package.json contents:

 "devDependencies": {
        "jsxc": "~0.1.6",
        "browserify" : "^6.2.0",
        "reactify": "^0.15.2",
        "envify": "3.2.0",
        "jest-cli": "~0.1.17",
        "uglify-js": "~2.4.15",
        "watchify": "^2.1.1"
    },
    "scripts": {
        "start": "watchify -o js/bundle.js -v -d .",
        "build": "NODE_ENV=production browserify . | uglifyjs -cm > js/bundle.min.js",
        "test": "jest"
    },
    "browserify": {
        "transform": [
            "reactify",
            "envify"
        ]
    },

Set environment variables from the file

Would be lovely, if envify supported setting env variables from the file (e.g. .env):

$ envify -f .env

.env:

VAR1=abc
VAR2=cba

Real use case: storing API keys for some services (e.g. MapBox) in .env file and wanting to replace process.env.API_KEY in code with those values.

Doesn't support object destructuring or accessing process.env object

It took me about 2 hours of debugging to release this, but when you think about how envify works, it makes sense. I was using object destructuring to cut down on some boilerplate, which works fine in node:

const {
  VAR_A,
  VAR_B,
  VAR_C
} = process.env

And none of them were being set. So I added a console.log(process.env) beneath it, which output {}, and that made me think envify wasn't being executed at all. Of course it's because envify is parsing the file looking for process.env.SOMETHINGHERE literally.

It would be nice if object destructuring were supported, though I can understand why it would be challenging, and accessing process.env would almost always be a mistake (except for debugging). Perhaps the solution here is just to make this more clear in the readme, that this module doesn't actually provide a process.env object; it basically just does string replacing?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.