Giter Club home page Giter Club logo

jsdom-global's Introduction

jsdom-global

Enables DOM in Node.js

jsdom-global will inject document, window and other DOM API into your Node.js environment. Useful for running, in Node.js, tests that are made for browsers.

Status

Install

Requires jsdom.

npm install --save-dev --save-exact jsdom jsdom-global

Note

jsdom-global now requires jsdom v10 or above. If you need jsdom v9 and below, use the previous version (jsdom-global@2).

Usage

Just invoke it to turn your Node.js environment into a DOM environment.

require('jsdom-global')()

// you can now use the DOM
document.body.innerHTML = 'hello'

You may also pass parameters to jsdomGlobal() like so: require('jsdom-global')(html, options). Check the jsdom.jsdom() documentation for valid values for the options parameter.

To clean up after itself, just invoke the function it returns.

var cleanup = require('jsdom-global')()

// do things

cleanup()

Tape

In tape, run it before your other tests.

require('jsdom-global')()

test('your tests', (t) => {
  /* and so on... */
})

Mocha

Simple: Use Mocha's --require option. Add this to the test/mocha.opts file (create it if it doesn't exist)

-r jsdom-global/register

Advanced: For finer control, you can instead add it via mocha's before and after hooks.

before(function () {
  this.jsdom = require('jsdom-global')()
})

after(function () {
  this.jsdom()
})

ES2015

If you prefer to use import rather than require, you might want to use jsdom-global/register instead. Place it on top of your other import calls.

import 'jsdom-global/register'
import React from 'react'
import jQuery from 'jquery'
// ...

Browserify

If you use Browserify on your tests (eg: smokestack, tape-run, budo, hihat, zuul, and so on), doing require('jsdom-global')() is a noop. In practice, this means you can use jsdom-global even if your tests are powered by browserify, and your test will now work in both the browser and Node.

  • Writing your tests (test.js):

    require('jsdom-global')()
    
    // ...do your tests here
  • Running it with smokestack:

    browserify test.js | smokestack          # run in a browser
    node test.js                             # or the console
    browserify test.js --no-bundle-external  # also works (but why bother?)
  • Running it with Babel (babelify or babel-cli):

    browserify test.js -t babelify | smokestack  # run in a browser (with babel)
    babel-node test.js                           # or the console

Thanks

jsdom-global © 2016+, Rico Sta. Cruz. Released under the MIT License.
Authored and maintained by Rico Sta. Cruz with help from contributors (list).

ricostacruz.com  ·  GitHub @rstacruz  ·  Twitter @rstacruz

jsdom-global's People

Contributors

coryhouse avatar jtag05 avatar kenjiru avatar rstacruz 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

jsdom-global's Issues

MutationObserver

I'm trying to add MutationObserver to a jsdom-created DOM like this, but for some reason the script doesn't seem to load:

require('jsdom-global')(
  '', 
  {
    scripts: [
      'https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/0.7.22/MutationObserver.js',
    ],
  }
)
ReferenceError: MutationObserver is not defined

This browser doesn't support requestAnimationFrame and cancelAnimationFrame.

Seeing the following warnings when running tests using this setup:

This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills
This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills

I am currently using the fork at the pull request #42, which resolves the issue and waiting for it to be merged into the main branch.

Thanks!

Support for jsdom ~v10.0.0

New release of jsdom has a different pattern for initialization:

const jsdom = require("jsdom");
const { JSDOM } = jsdom;

which causes such error:

.../node_modules/jsdom-global/index.js:29
  var document = jsdom.jsdom(html, options)
                       ^

TypeError: jsdom.jsdom is not a function
    at globalJsdom (.../node_modules/jsdom-global/index.js:29:24)
    at Object.<anonymous> (../node_modules/jsdom-global/register.js:1:19)
    at Module._compile (module.js:570:32)
    at Module._extensions..js (module.js:579:10)
    at Object.require.extensions.(anonymous function) [as .js] (.../node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at ../node_modules/mocha/bin/_mocha:345:3
    at Array.forEach (native)
    at Object.<anonymous> (../node_modules/mocha/bin/_mocha:344:10)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:393:7)
    at startup (bootstrap_node.js:150:9)
    at bootstrap_node.js:508:3

Using localStorage and sessionStorage

I just ran into an issue where a library I'm using uses sessionStorage, so I'm getting sessionStorage is not defined in my tests. Is there any plan to support these types of storages in jsdom-global?

After some research I noticed there is a PR in jsdom that's pretty related. Would jsdom-global then just need to put them in the global scope like it does document and window?

jsdom/jsdom#2076

ES6 - custom HTML to test

Great plugin. I'm just wondering if there's a way in ES6 that after importing (import 'jsdom-global/register';) I can set custom HTML so I can test things like click events that add classes etc.

Thanks!

Can't define 'window' object after Browserifying my test file. Is that expected?

Hello. I'm a little unclear on whether this package should work with Browserify or not. The README seems to indicate 'yes,' but my experience indicates 'no'. Maybe I'm doing something wrong :-/

In short, in a unit test, I can successfully use require('jsdom-global')() to define the window object. But if I then Browserify/Babelify the test file, then run execute the unit test, the window object is no longer defined. Is that expected?

Here is a more detailed description.

  1. I created a file test\tape.test.update.js. It simply requires jsdom-global, defines a simple test (using Tape), and prints the value of the window object:
require('jsdom-global')()
let tapeTest = require('tape')

tapeTest('Test update functions.', function(t) {
  console.log(window)
  t.end()
})
  1. From the Node command line, if I execute node test/tape.test.update.js, the window object is defined, as desired/expected.

  2. From the command line, I then Browserified (with a Babelify transform) the file, like so:

node_modules/.bin/browserify test/tape.test.update.js -t [ babelify ] --outfile test/test-bundle.js

  1. From the command line I then executed

node test/test-bundle.js

  1. It returns a ReferenceError:

ReferenceError: window is not defined


Is this expected? If so, is there a way to use jsdom-global in my case?

The README has a section about Browserify. The first sentence reads,

If you use Browserify on your tests (eg: smokestack, tape-run, budo, hihat, zuul, and so on), doing require('jsdom-global')() is a noop.

To me, this says that I should not expect the window object to be defined in my case.

But the next sentence reads,

In practice, this means you can use jsdom-global even if your tests are powered by browserify, and your test will now work in both the browser and Node.

To me, this says that I should expect the window object to be defined in my case.

Sorry to be a pain here--I know I'm getting into semantics a bit :-/ Just wondering if I'm doing something wrong, or if I should look for another solution.


Version Numbers

  • jsdom: 16.5.2
  • jsdom-global: 3.0.2
  • browserify: 16.5.1
  • babelify: 10.0.0
  • tape: 5.0.1

Issue when using mocha and sinon fake server after upgrading to 2.1.0

I'm not sure if this issue belongs here, but after upgrading to jsdom-global 2.1.0, sinon fake server does not mock responses. Instead the responses are being sent to the actual server. Pinning the version of jsdom-global to 2.0.0 fixes the issue. Is this something that you have come across?

Add support for SVGElement?

The jsdom package appears to support SVGElement now. Can support for SVGElement be added to jsdom-global?

Thanks!

Unix only?

This is how it crashes for me:

npm ERR! code ENOENT
npm ERR! syscall rename
npm ERR! path C:\dev\React-TDD-Gift-Giver\node_modules\acorn-globals\node_modules\acorn
npm ERR! dest C:\dev\React-TDD-Gift-Giver\node_modules\acorn-globals\node_modules\.acorn.DELETE
npm ERR! errno -4058
npm ERR! enoent ENOENT: no such file or directory, rename 'C:\dev\React-TDD-Gift-Giver\node_modules\acorn-globals\node_modules\acorn' -> 'C:\dev\React-TDD-Gift-Giver\node_modules\acorn-globals\node_modules\.acorn.DELETE'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\derek\AppData\Roaming\npm-cache\_logs\2020-11-30T22_48_51_788Z-debug.log

This was with

npm install --save-dev --save-exact jsdom jsdom-global

Stupid Question About JSDom

I'm sure there's a very good reason for this, but since I'm not aware of it I had to ask: why tell people to install the JSDom module separately, when you could just make it a dependency of jsdom-global?

FileReader not working

fileReader = new FileReader() doesn't appear to be working, although new File() works, is this intended? It appears to be implemented in jsdom according to the version 7 changelog.

Differences in scope/context when calling via CLI vs. include

I hope I'm not missing something obvious but have spent quite a bit of time trying to solve this before creating an issue.

I am using mocha as my test runner for historical reasons and attempting to test React components using @testing-library/react. I've come across what seems to be a scope/context issue between the command-line --require directive vs. including directly in the test file.

My npm test script is as follows:

"test:client": "npx mocha -r jsdom-global/register -r @babel/register -recursive 'client/**/test.js'",

I've pasted the full script in case there's something else that can be spotted. When I run the script above on a test that does not explicitly import jsdom-global I get an output like this:

image

Note that screen.debug() outputs an empty <body /> element.

If I remove the -r jsdom-global/register option and explicitly add import 'jsdom-global/register' in my test file, I get:

Screen Shot 2020-11-05 at 8 35 21 am

...

Screen Shot 2020-11-05 at 8 34 55 am

As you can see, in the second example including jsdom-global/register via an explicit import in my test file appears to make the DOM available to screen, but requiring it via mocha on the command line does not.

Both methods appear to make an identical document global available:

image
image

Node.js URL gets undefined

Hey,

just had this weird behaviour with the following code:

const jsdomGlobal = require('global-jsdom');

console.log(URL, "Test 1");
const cleanup = jsdomGlobal("<html><body></body></html>");
console.log(URL, "Test 2");
cleanup();
console.log(URL, "Test 3");

Test 1 and Test 2 print to the console just as expected, however Test 3 throws ReferenceError: URL is not defined

Invalid URL error

I'm getting the following error when importing into ES6 tests like this import 'jsdom-global/register'.

<project-root>/node_modules/whatwg-url/lib/URL-impl.js:19
      throw new TypeError("Invalid URL");

TypeError: Invalid URL

Do you know why this could be?! Thanks

pass the options to jsdom

For mocking REST calls made with CujoJS rest package (https://github.com/cujojs/rest), we need to specify the location, otherwise it fails.

According to https://github.com/tmpvar/jsdom#for-the-hardcore-jsdomjsdom this can be done using the second options parameter.

var document = jsdom.jsdom(html, {
    url: "http://localhost"
});

I would make even the html parameter configurable. Or course, provide a default value, but offer the user the possibility to change it, if he needs to.

[Discussion] [Support needed] Best way to use jQuery

This code seems to be working:

var jsdom = require('jsdom');

this.jsdom = require('jsdom-global')(
  htmlContent
);

// The second jsdom instance is used
jsdom.jQueryify(window, "http://code.jquery.com/jquery.js", function () {
   done()
});

But it requires to use second jsdom instance : I cannot access jsdom from 'jsdom-global'

Is there antipattern? Is there another way to use jQuery and another libs?

Is there good idea to expose jsdom instance from jsdom-global?

any idea why this does not work with create-react-app?

I made src/setupTests.js with:
import 'jsdom-global/register'

but when jest runs, it shows this error:

/home/ali/projects/x_project/x/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:75
      throw new TypeError("Argument to dispatchEvent must be an Event");
      ^
TypeError: Argument to dispatchEvent must be an Event
    at EventTargetImpl.dispatchEvent (/home/ali/projects/x_project/x/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:75:13)
    at Window.dispatchEvent (/home/ali/projects/x_project/x/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:61:35)
    at Window.process.nextTick (/home/ali/projects/x_project/x/node_modules/jsdom/lib/jsdom/browser/Window.js:492:14)
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)

Solution to conditionally including jsdom-global in node environment

I have a situation where I am developing web modules with es6/mocha/chai/sinon/jsdom. I have some basic TDD-style mocha-watch commands set up to re-run tests in the terminal. The problem is, I also want to be able to run tests in the browser. I have an HTML file setup to do so, but I'm not sure how to handle the jsdom-global piece.

I would like to not have jsdom run in browser (to test actual browser functionality). Is there a recommended way to do this? I was thinking of some sort of setup script that would conditionally include jsdom if it detected it wasn't in a browser. Open to any ideas/recommendations, even if you say it's a terrible idea to try to do that.

jsdom as peerDependency

jsdom should be marked as peerDependency because tools like depcheck complain about unused dependency which is required by your lib ;)

Globalizing window keys

Please see: jsdom/jsdom#1549

From their changelog for v9.4.0:

Fixed all constructors that appears as globals on the jsdom window object to be non-enumerable.

This means that these lines no longer work:

jsdom-global/index.js

Lines 37 to 41 in bc52cfe

Object.keys(window).forEach(function (key) {
if (blacklist.indexOf(key) !== -1) return
keys.push(key)
global[key] = window[key]
})

Object.keys(window).forEach(function (key) {
  if (blacklist.indexOf(key) !== -1) return
  keys.push(key)
  global[key] = window[key]
}))

I'm not exactly sure if they have a better API to allow globalizing the window properties.. So I'm waiting for a reply until I can suggest a solution. But maybe you have some thoughts around this.

Cheers!

Travis unit tests failing with 'window is not defined'

Hi there,

In our unit tests we use the following construct to initialize jsdom-global:

before(function() {
    this.jsdom_global = jsdom_global(
      "<div id='mynetwork'></div>",
      { skipWindowCheck: true}
    );
    this.container = document.getElementById('mynetwork');
  });

  after(function() {
    this.jsdom_global();
  });

The unit tests work perfectly when run locally, but it happens regularly that they fail on Travis:

1) Network "after all" hook:
     Uncaught ReferenceError: window is not defined
      at CanvasRenderer._requestNextFrame (dist/vis.js:50457:22)
      at CanvasRenderer._requestRedraw (dist/vis.js:50540:14)
      at Network.Emitter.emit (dist/vis.js:6493:20)
      at View.animateView (dist/vis.js:51596:29)
      at View.moveTo (dist/vis.js:51536:12)
      at View.fit (dist/vis.js:51462:12)
      at Network.Emitter.emit (dist/vis.js:6493:20)
      at PhysicsEngine._finalizeStabilization (dist/vis.js:47781:27)
      at PhysicsEngine._stabilizationBatch (dist/vis.js:47767:14)

After this happens, other unrelated unit tests tend to fail as well as a consequence.
I don't fully understand the mechanics of execution on Travis, but by the looks of it, the global window is cleared while (apparently) overlapping unit tests are running.

Is there any way to avoid this error?

As a stopgap measure, I'm considering just catching the ReferenceError for this particular case; I see in the code that window is the very last item in the list of keys, so everything else would have been cleaned up on the call to jsdom_global() in the after-hook. Would this be acceptable? If you know of any other solutions, I would love to know.


This is my current working hypothesis on this error:

In our code, window.requestAnimationFrame is used to trigger the drawing of a next frame on a Canvas element. The final frame redraw can be delayed, and it's possible that this overlaps with the subsequent unit test (on Travis). Because of this, the global window could be reset while another test is running, causing the given error.

testing stateless component in react gives - TypeError: Cannot set property event of #<Window> which has only a getter

I am using jsdom-global library but facing this issue when I do mount with enzyme.

describe('', function () {
it('should render 4 menu options', function () {
const handleSearchCallBack = (event) => {
};
const wrapper = mount();
});
});

import Button from '@material-ui/core/Button';
import SearchIcon from '@material-ui/icons/Search';
import React from 'react';
const TextIconSearchButton = ({handleOnClick}) => (

} >
); export default TextIconSearchButton;

On running a test, mocha --require @babel/register --require test/testSetup.js -require jsdom-global/register,
it continously printed below error
Error: Uncaught [TypeError: Cannot set property event of # which has only a getter]

and then,

Invariant Violation: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

This happens when I do mount instead of shallow.
at this line from react-dom.js
if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
window.event = windowEvent;
}

"jsdom-global": "3.0.2",
"react": "16.8.2",
"enzyme": "^3.11.0",

Can't access the JSDOM API

As of version 3, there's no way to access the JSDOM api (here) directly. Some functions such as reconfigure are important.

How do you think we can expose a reference to it? Please guide me and I'll be happy to make a PR.

Thanks!

JSDOM Issue before all" hook: Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

I was getting
before all" hook:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
For

before(function () {
  this.jsdom = require('jsdom-global')()
})

after(function () {
  this.jsdom()
})

Changing above lines code to import statement below resolved the issue.

import 'jsdom-global/register'; 

Stating here , so in case anybody else encounter the same will have a solution. Thanks!

Not implemented: window.alert

After upgrading to the new version of jsdom and jsdom-global I am getting this issue. Code that I am testing has this line inside of it window.alert('Please try again'). It was not a problem until now?

Thanks

delete window.propertyName doesn't work

Run into a problem using mocha tests with jsdom, delete window.propertyName; doesn't work. So after this command window.propertyName is still defined. So my tests failed. I have workaround use window.propertyName = undefined; which works fine, but I expected to use delete keyword.

Running jsdom with jest

I'm getting this error while i'm trying to run jest tests.
node: 7.11.0
npm: 4.2.0
jest: 20.0.4
jsdom: 11.0.0

html-to-json/node_modules/jsdom/lib/jsdom/living/generated/Event.js:231
    throw new TypeError(`${context} is not of type 'Event'.`);
    ^

TypeError: Failed to execute 'dispatchEvent' on 'EventTarget': parameter 1 is not of type 'Event'.
    at convert (html-to-json/node_modules/jsdom/lib/jsdom/living/generated/Event.js:231:11)
    at Window.dispatchEvent (html-to-json/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:88:13)
    at Window.process.nextTick (html-to-json/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/browser/Window.js:492:14)
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickCallback (internal/process/next_tick.js:104:9)

I'm running require('jsdom-global')() on my setup.js jest file and also inside the file that i using jsdom

I also tried to write my own code and it worked for jest but didn't work from some reason on my production server.

const { JSDOM } = require('jsdom');

const jsdom = new JSDOM('<!DOCTYPE html><html><head></head><body></body></html>');
const { window } = jsdom;

function copyProps(src, target) {
  const props = Object.getOwnPropertyNames(src)
    .filter(prop => typeof target[prop] === 'undefined')
    .map(prop => Object.getOwnPropertyDescriptor(src, prop));
  Object.defineProperties(target, props);
}

global.window = window;
global.document = window.document;
global.navigator = {
  userAgent: 'node.js',
};
copyProps(window, global);

I will keep investigate this issue just wonted to point that out and see if there is a quick fix for this issue.
thanks,

How to use cleanup() with ES6 modules?

Hey I know you can't spend too much time on this project anymore, but I just thought I'd ask, in case there's a relatively quick/easy answer. In the Usage section, it describes a way to cleanup, by calling cleanup like so:

var cleanup = require('jsdom-global')()
cleanup()

But what if I'm importing using ES6 modules? Then require is not defined. So is there another way to define cleanup? I tried a few ways, using the import keyword, but couldn't get anything to work :-/

If cleanup is instead something I need to do myself, in a more manual manner, that's fine--just let me know.

Identification of the `window` object with the `global` object

First of all, thanks for the interesting and useful solution, which jsdom-global definitely is.
Though let me notice there is still a difference between the real browsers behavior and the environment emulated on the node using jsdom-global. In the real browser:

window.foo=1;
typeof foo; // => 'number'

Unfortunately in the emulated environment on node -r jsdom-global/register:

window.foo=1;
typeof foo; // => 'undefined'

Let me ask - is it possible to fix the above disadvantage?

I have the impression that identifing window with global seems to be easy achievable by changing in the jsdom-global/index.js only the little piece of the existing code:

  KEYS.forEach(function (key) {
    global[key] = window[key]
  })
  
  global.document = window.document  // change
  global.window = window             // change
  window.console = global.console    // change
  document.destroy = cleanup

as follows:

  KEYS.forEach(function (key) {
    global[key] = window[key]
  })
  
  global.window=global    // changed
  document.window=global  // changed
  document.destroy = cleanup

Now in the emulated environment on node -r jsdom-global/register we have

window.foo=1;
typeof foo; // => 'number'

Unfortunately it is not the correct solution - for example after the change the window.DOMParser lost, though DOMException, DOMImplementation or DOMTokenList are available as globally as well as the window members...
(I suppose the cleanup behavior may also require some tuning because after the proposed change it could be the "one way ticket")

Resetting js dom multiple times during mocha tests

I'm using jsdom-global in context with mocha tests, testing a react application.

The test infrastructure is built around integration tests, using enzyme's mount method. I noticed, that react is using the DOM as storage place for internal logic. This is causing side-effects between the tests which are impossible to debug. I would like to freshly setup the DOM before every test runs.

Do you have an idea, how to reset the jsdom/jsdom-global at runtime between tests? Using the mocha hooks did not work. It seems that once babel-register is activated to compile test and source, jsdom-global stops working. In other words, how can jsdom-global be used after babel-register has compiled the code?

I appreciate any input.

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.