Giter VIP home page Giter VIP logo

redux-dynamic-modules's Introduction

logo

Redux Dynamic Modules

Pipelines npm (scoped) Join the chat at https://gitter.im/redux-dynamic-modules/community GitHub license

What is it?

redux-dynamic-modules is a library that aims to make Redux Reducers and middleware easy to modular-ize and add/remove dynamically.

Motivation

In large Javascript applications, it is often desired to perform some kind of code-splitting, so that the initial script size is small. However, in Redux, you are required to define your reducers and middleware up-front; there is no good way to dynamically add/remove these constructs at runtime.

redux-dynamic-modules is designed to make dynamically loading these constructs easier. You can define a module, which contains reducers and middleware, and add it to the Redux store at runtime. We also provide a React component DynamicModuleLoader, which can load/unload modules on mount/unmount.

Modules provide the following benefits:

  • Modules can be easily re-used across the application, or between multiple similar applications.
  • Components declare the modules needed by them and redux-dynamic-modules ensures that the module is loaded for the component.
  • Modules can be added/removed from the store dynamically, ex. when a component mounts or when a user performs an action

Features

  • Group together reducers, middleware, and state into a single, re-usable module.
  • Add and remove modules from a Redux store at any time.
  • Use the included <DynamicModuleLoader /> component to automatically add a module when a component is rendered
  • Extensions provide integration with popular libraries, including redux-saga and redux-thunk

Example Scenarios

  • You don't want to load the code for all your reducers up front. Define a module for some reducers and use DynamicModuleLoader and a library like react-loadable to download and add your module at runtime.
  • You have some common reducers/middleware that need to be re-used in different areas of your application. Define a module and easily include it in those areas.
  • You have a mono-repo that contains multiple applications which share similar state. Create a package containing some modules and re-use them across your applications

Install

Run

npm install redux-dynamic-modules

or

yarn add redux-dynamic-modules

Usage

  • Create a module with the following format
export function getUsersModule(): IModule<IUserState> {
    return {
        id: "users",
        reducerMap: {
            users: usersReducer,
        },
        // Actions to fire when this module is added/removed
        // initialActions: [],
        // finalActions: []
    };
}
  • Create a ModuleStore
import { createStore, IModuleStore } from "redux-dynamic-modules";
import { getUsersModule } from "./usersModule";

const store: IModuleStore<IState> = createStore({
      initialState: { /** initial state */ },
      enhancers: [ /** enhancers to include */ ], 
      extensions: [/** extensions to include i.e. getSagaExtension(), getThunkExtension() */],
},
    getUsersModule()
    /* ...any additional modules */
);
  • Use like a standard Redux store
  • Use the DynamicModuleLoader React component to add/remove modules when components mount/unmount
<DynamicModuleLoader modules={[getHelloWorldModule()]}>
    <div>Hello World!!</div>
</DynamicModuleLoader>

Extensions

Examples

See the Widgets for a quick of example of the library in practice.

Step by step walthrough of start consuming redux-dynamic-modules in the widget app. Youtube

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

redux-dynamic-modules's People

Contributors

abettadapur avatar ajaypantangi avatar andyhmltn avatar anilanar avatar bpedersen avatar cschleiden avatar denisborovnev avatar dependabot[bot] avatar djsilcock avatar exogen avatar fraserkillip avatar gitter-badger avatar luskin avatar microsoft-github-policy-service[bot] avatar microsoftopensource avatar mohitbagra avatar msftgits avatar navneet-g avatar reneviering avatar santojambit avatar shinvey avatar shutchings avatar simarmol avatar tu4mo avatar zyh41 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redux-dynamic-modules's Issues

DynamicModuleLoader's children mounts twice

Due to the following workaround:

https://github.com/Microsoft/redux-dynamic-modules/blob/e1046942f26db108f7dbb6ccc593824c9de716f5/packages/redux-dynamic-modules/src/DynamicModuleLoader.tsx#L142-L147

children of DynamicModuleLoader is mounted twice, once with a <Provider> wrapper and once without the wrapper.

I think this workaround is not needed anymore since React 16.6.3 and store.getState() gives the correct state on first render.

Nevermind, it still behaves the same. I forked and unconditionally wrapped the component with the Provider always, which is better than double mounting IMO and has no side effects AFAIK.

Strategies for hydrating a store from SSR

Hi there, I'm experimenting with this package and have been pleasantly surprised so far. Good job!

I wonder if it would be worthwhile to add some documentation about possible solutions to deal with server-side rendering. A typical server-side rendered Redux setup looks like this:

  1. On each request to the server, a fresh Redux store is created for that request.
  2. When generating the response body, the Redux state for that request is serialized into the HTML.
  3. When the client hydrates, a new global client-side Redux store is created and preloaded with the serialized state.

Maybe you can see the problem: on the server, some arbitrary set of dynamic Redux modules may have been loaded. On the client, we get the state those modules created, but we have a new store instance without any modules actually loaded. Besides inferring it from what state exists in the store, there's no indication of which modules need to be loaded to deal with that state. The set of loaded modules is effectively part of the Redux store's state, but one that hasn't been serialized from server to client.

You might think DynamicModuleLoader is a good enough solution for this, since it should result in the same modules being loaded on client and server if the same tree is rendered (like it should). The issue is that often, data needs to be fetched ahead of time (e.g. with Redux) before a component tree is even created/decided upon, since (until Suspense arrives) there is no way to "wait" for data during SSR. So, frameworks invent new lifecycle hooks to do this fetching, like getInitialProps in Next.js. In this hook, you'd need to use Redux, fire actions, etc., but any module you'd need would have to be added imperatively with addModules.

The set of loaded modules must be communicated in a serializable way, like an array of strings. This could be the module IDs (you'd need to keep a global mapping of ID → module in order to actually load them, which might defeat the purpose of splitting everything up in the first place), or perhaps the module path (so it can be dynamically imported).

That leaves the issue of initialActions: AFAIK, if the initial actions were already fired on the server, there's no way to tell the client-side store to skip those actions. Some actions, depending on their side effects, might be necessary to fire on both the client and server, while others you'd want to skip if the server already fired them. This could be handled with some bookkeeping in the module's own store state, like bootstrapped: true or something, or maybe you could dynamically modify the module to exclude initialActions when necessary on the client...

Anyway, I wonder if anyone else has thought about this, and what your approach is.

Remove react / react-redux from redux-dynamic-modules

Is there any reason, other than convenience, that react and react-redux are in the redux-dynamic-modules package.json? I'm currently experimenting with using this as a headless redux layer that can be ported to different presentation layers e.g. React, React Native, possibly angular-redux.

It'd be great if this library didn't contain those dependencies.

Suggestion for React HOC Wrapper for DynamicModuleLoader

There may be many folks, including myself, that prefer the "withSomeFeature" HOC style for initiating a Redux module load. To that end, have provided some working code below.

I am posting here instead of submitting, as I don't know if there is a better way to achieve this or not... but feel free to use the code as-is

// withReduxDynamicModule.tsx
import React from 'react';
import { IModuleTuple } from 'redux-dynamic-modules-react';
import { DynamicModuleLoader } from './DynamicModuleLoader';

const withReduxDynamicModule = <P extends object>(dynamicReduxModules: IModuleTuple, keepModulesOnUnmount: boolean = false) => (WrappedComponent: React.ComponentType<P>) => {
  return class WithReduxDynamicModules extends React.Component<P> {
    render() {
      return (
        <DynamicModuleLoader modules={dynamicReduxModules} keepModulesOnUnmount={keepModulesOnUnmount}>
          <WrappedComponent {...this.props as P} />
        </DynamicModuleLoader>
      );
    }
  };
};

export default withReduxDynamicModule;

Pass options to devtools

Although it is convenient to include devtools integration in this library, there's a fair question to ask here: is it this library's responsibility to do it? If it's done for technical reasons, I think we need a way to pass options to the devtools' compose function.

Particularly action blacklisting, state sanitization, max-age are invaluable for large apps.

In addition, different apps have different needs (e.g. using devtools in production etc.). There are infinitely many possible ways to configure devtools. What if createStore took a compose function as a parameter?

Another alternative (as seen in other issues/questions submitted) is to have an additional API that exports enhancers/middlewares for dynamic module management and let users seeking more freedom use createStore from redux.

If you would like to go with the first option (adding compose param to createStore), I can make a PR. I suggest that createStore’s first argument is made an options object in that case e.g. createStore<...>(options: { compose, initialState, enchancersEtc }, ...modules). I’m typing from mobile so this is not a type signature 😄

It seems it’d be better if this were done after #55 is merged. Nevertheless this will be a breaking change.

Usage with redux-persist

Hi there!

I really like this library - and I also really like redux-persist which allows to save parts of the store to local storage. Unfortunately both this module and redux-persist require to use their own method to create a redux store, and these methods are not chainable if I am not mistaken.
What would the preferred way to solve this? If there is no way yet but an idea of how to solve this as an additional feature in this library, I would be willing to try myself on a PR.
I have also opened an issue with the other repo.

Best,
Daniel

Initializing store

I am having issues initializing the store with the createStore provided via readux-dynamic-modules. I am most certainly doing something wrong, but could not figure out what. Any help would be appreciated.

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
        ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
        // Options: http://zalmoxisus.github.io/redux-devtools-extension/API/Arguments.html
            actionCreators,
        })
        : compose;

    enhancers.push(applyMiddleware(...middleware));

    const enhancer = composeEnhancers(enhancers);
// With initial state
// ERROR: Uncaught (in promise) TypeError: Cannot read property 'concat' of undefined
const store = createStore(
                reducers(history),
                initialState,
                enhancer,
                [getSagaExtension({})],
            );
// Without initial state
// Error: It looks like you are passing several store enhancers to createStore(). This is not supported
const store = createStore(
                reducers(history),
               //  initialState,
                enhancer,
                [getSagaExtension({})],
            );

where should i put my enhancers?

hi all, i use redux's createStore and compose like this

const enhancers = [firebaseEnhancer, middlewareEnhancer, offlineEnhancer];
const createEnhanceStore = compose(...enhancers)(createStore);

export const createReduxStore = (initialState) => createEnhanceStore(makeRootReducer(), initialState);

and in redux-dynamic-modules , i check the code, i can put middleware in a new extension like redux-dynamic-modules-thunk , but where i should put the other enhancers?

the ModuleStore only compose middleware ,

https://github.com/Microsoft/redux-dynamic-modules/blob/10e7526f037dba0f1260a913f241504ea41f51ad/packages/redux-dynamic-modules/src/ModuleStore.ts#L43

am i wrong ?

mapStateToProps not initialize state

I use redux-dynamic-modules/todo-example after run below error.

src/containers/root/FilterLink.js:6
TypeError: Cannot read property 'visibilityFilter' of undefined

const mapStateToProps = (state, ownProps) => ({
   active: ownProps.filter === state.root.visibilityFilter,
});

I use redux-dynamic-modules@^3.3.1, in my project too same error.

Implement changelog

This lib is really cool and helps to write modern web apps very much. Thank you!
I just would like to request a changelog here to be sure what I'm doing on each dependency upgrade

Multiple reducer default state throws error

Version: 3.5.1

Behaviour: If I have multiple modules, with multiple reducers loading on the initial createStore call, the reducer values are ignored. This creates issues when unit testing connected components as re-renders aren't being captured when asserting behaviour.

Expected: I should be able to declare an initial state for multiple reducers

e.g.

//createStore.js

createStore(
  initialState,
  [applyMiddleware(analyticsMiddleware)],
  [getThunkExtension()],
  getUserDataStoreModule(), // creates reducer UserDataStore
  getAnalyticsModule(), // creates reducer Analytics
  getSubmissionModule() //creates reducer SubmissionStore
);

//app.js
createStore({
  UserDataStore: { a: 1, b: 2 },
  Analytics: { a: 1, b: 2 },
  Submission: { a: 1, b: 2 }
});

Throws error in redux.js:
Unexpected keys "Analytics", "SubmissionStore" found in previous state received by the reducer. Expected to find one of the known reducer keys instead: "UserDataStore". Unexpected keys will be ignored.

As this is occurring in my unit test environment in a beforeEach hook, the second unit test also throws an error, this time:
Unexpected key "SubmissionStore" found in previous state received by the reducer. Expected to find one of the known reducer keys instead: "UserDataStore", "Analytics". Unexpected keys will be ignored.

Current workaround is to lock version at 3.5.0.

Support React-Redux V6

React-Redux v6 will use React's ( new ) context api which is not compatible with the legacy context API. By accessing store from context ( reference ) it causes the app to break when it tries to dynamic load modules.

"Could not load store from React context" - Error is thrown in DynamicModuleLoader.

As @timdoor has described in its breaking changes:

Passing store as a prop to a connected component is no longer supported. Instead, you may pass a custom context={MyContext} prop to both and . You may also pass {context : MyContext} as an option to connect.

Possible bug when used with React-Redux v7

redux-dynamic-modules-react currently has this chunk of code:

https://github.com/Microsoft/redux-dynamic-modules/blob/8d9bbbbb037abeae2b3f4f62345668097c0f8015/packages/redux-dynamic-modules-react/src/DynamicModuleLoader.tsx#L141-L150

This was related to a bug that popped up in React-Redux v7 beta 0, at reduxjs/react-redux#1219 .

Looking at the code further, I can see that you're rendering a <ReactReduxContext.Provider> with your own value. By doing that, you're actually going to completely override the context value from React-Redux itself. That context value normally looks like {store, subscription] in v7. Based on your code, the subscription value will be lost, and nested connected components will not be updated in the correct sequence, and will not take advantage of React's batched updates.

I'd suggest changing this chunk to render both a <ReactReduxContext.Consumer> and a <ReactReduxContext.Provider>, pass down a context value that looks like {store, storeState, subscription}, and memoize producing that value so that it doesn't keep changing on every render (to avoid unnecessary context-caused updates).

Module is remove, when clicking react router links, inside the same module

Hey,
Maybe there is something I dont know of the inner workings,
But when I have a ReactRouter NavLink that point to another page,
within the same module, a '@@Internal/ModuleManager/ModuleRemoved'
is still dispactehed, which remove the data for the module,
and break our site.
When I hard reload the browser the module is again loadet correct.

So it seems that react router links dont really works inside a module ?

It seems like a bug?

Is it posible to turn of 'ModuleRemoved' ?

Redux history:

[
{
  type: '@@router/LOCATION_CHANGE',
  payload: {
    location: {
      pathname: '/contracts/activities',
      search: '',
      hash: '',
      key: '0yjca4'
    },
    action: 'PUSH',
    isFirstRendering: false
  }
},
{
  type: '@@Internal/ModuleManager/ModuleRemoved',
  payload: 'contract'
}
]

Redux state removed before components unmount

I'm seeing an issue when navigating where, when a DynamicModuleLoader component is being removed, the connected container components are still reading from state after the state has already been removed but before the component has dismounted. This leads to reference errors when matchStateToProps is trying to read state.x.y (cannot read property y of undefined) because state.x was already removed. I know I can check if that property exists first, but there seems to be an underlying issue that's causing state to be removed before the component umounts. Using react-redux 7.0.2, react 16.8.6, and redux-dynamic-modules 3.5.0

Cannot read property 'Consumer' of undefined

Hi I have started using this module been getting this issue
the functionality breaks in DynamicModuleLoader.render function where it tries to find .Consumer

return (React.createElement(react_redux_1.ReactReduxContext.Consumer, null, function (reactReduxContext) { return (React.createElement(DynamicModuleLoaderImpl, __assign({}, _this.props, { reactReduxContext: reactReduxContext }))); }));

i am using react-redux version 5.0.7 Please Suggest How to Proceed ?
Screenshot 2019-06-11 at 5 38 24 PM

Redux - Devtools are broken in release 2.0.1

The new ModuleEnhancer is composing the enhancers without redux devtools by using the plain compose method of redux and so the store is not recognized in the tools.

Fix in ModuleEnhancer.ts:

let composeEnhancers = compose;

if (process.env.NODE_ENV === "development") {
composeEnhancers = window["REDUX_DEVTOOLS_EXTENSION_COMPOSE"] || compose;
}

Modules as External/NPM packages

Thanks for this great library!

This library has inspired me to consider modularizing some components so other people who are using this library can enjoy them via the NPM communal registry.

For projects which are set up correctly with a store, I'd like the developers of that project to consume my components simply via npm/yarn installation. They should then import them and the package should bind to their pre-existing store.

Currently, I'm experiencing a context error
Store could not be resolved from React context

Is it possibly something simple i'm overlooking here?

my notifications source can be found here:
https://github.com/Verikon/rdm-notifications

Hot reload slowdown

I'm experiencing a hot reloading slowdown after implementing redux-dynamic-modules and redux-dynamic-modules-saga (v3.2.0) in my medium-size application.
Is it something you are aware of?

Is there support for Hot Module Replacement?

Two questions:

  1. Is replaceReducer() supported by the store, and is there a way to substitute a saga?
  2. Is there any guidance (via example code or docs) to show how to correctly setup for HMR in reducer and/or saga code?

Communication between modules

What is the preferable way to communicate between modules? Maybe this question is not related directly to this lib. I use redux, redux-saga and redux-dynamic-modules.
The state of my rootModule holds magicBoolean variable. If it becomes true, RootComponent renders SomeLazyComponent, which loads dynamically (I use React.lazy). SomeLazyComponent contains DymanicModuleLoader which loads someDymanicModule. At one point I need to hide SomeLazyComponent and unload someDymanicModule. What I'm trying to do is to fire some action from someDymanicModule (or rootModule) and handle it in reducer (or saga) of rootModule to set magicBoolean variable to false and hide SomeLazyComponent. But in this case I have to import rootActionCreator to someDymanicModule to fire it from there, or to import ROOT_ACTION_NAME to root saga (beacause I need to know action name to handle it). What should I do in this case?

Issue: Adding enhancer that depends on a reducer

There are enhancers that depend on a reducer that adds to the state. I tried adding the Redux-first-router enhancer, but it throws an error that the state hasn't been set, because it's dependent on the Redux-first-router reducer.

The problem seems to be that redux-dynamic-modules adds the enhancer before adding the first/startup module. I'd like to be able to pass a reducer to the internal createStore with the RFR enhancer.

Is there a way to accomplish this?

Thanks.

Module type with sagas?

When declaring a module with sagas, TypeScript complains that IModule doesn't match. Is there another interface I can use or should I just return a plain object?

Fix the observable extension

The original idea for the observable extension did not work correctly
We need to figure out exactly how RxJS works and come up with a better option for dynamically loading Epics

Support for ImmutableJS reducer state

I'd love to use ImmutableJS with this project however, this project is hardwired to use redux's own combineReducers. Are the maintainers interested in refactoring the app to allow for less dependency on the underlying Redux state implementation?

Can each instance of the component has its standalone state in the redux store?

For example, in the Widgets example, the hacker-news has its unique id and the store key to the reducer. However, if I declare more than one instance of hacker-news, all instance will point to the same reducer and than all content of each hacker-news will be the same.

If I change the code in this way.

export function getHackerNewsModule(id) {
    const keyName = 'hackerNews' + id;
    const map = {};
    map[keyName] = hackerNewsReducer;

    return {
        // Unique id of the module
        id: keyName,
        // Maps the Store key to the reducer
        reducerMap: map,
        // Optional: Any actions to dispatch when the module is loaded
        initialActions: [fetchStories()],
        // Optional: Any actions to dispatch when the module is unloaded
        finalActions: [],
    };
}

each instance of hacker-news will have its standalone reducer in redux store and each instance can present own content.
Is this the correct way for my purpose?

Setting the a (static) first and last middleware

Hi,

Is it possible to make sure that a "static" middleware will always be the first/last in the middleware array?

In my case, I have an "action splitter" middleware that I use in order to send multiple actions in array. If the middleware gets an array, it dispatches each one of actions - (with 'next').
The last middleware is always a custom logger middleware and I need to make sure it's the last...

I would like to be able to add/remove middleware without having to worry about the index of the above middleware.
Thanks,
H.

Reset redux store on specific action

I try to reset the redux store (logout behavior) but I can't find a simple solution that allows me to do it globally when using redux-dynamic-modules.
Before using redux-dynamic-modules, I used to do what Dan was proposing here with the combineReducer function. https://stackoverflow.com/a/35641992/6765022
Now I understand that we have to send a map of reducers to the createStore function that will take care of everything.
Therefore, I cannot intercept the creation of the reducers to listen to a logout action. Anyone have any idea how to implement this behavior?

Typescript Recipes

Add some recipes for typescript, including concepts such as *AwareState

Feature request: Passing store to have it configured

Hi,

I have a feature request that might be useful for people who don't want to change how createStore or configureStore is used. I found it a bit confusing that I had to import createStore from this lib instead of Redux, and the params were in different order, and TBH I never got it to work with enhancers and redux-first-router.

How about this: We create the store as we've always done it before, but we'd simply pass the store to the library. And the library would simply add the reducer injection and other things it needs to make it a dynamic store.

So for example: const dynamicStore = reduxDynamicConfigure(store) or something.

What do you think?

Add more example options

Please add more examples, because there is now example on how we can test a component that has been wrapped in the DynamicModuleLoader ?

Dynamic Module Loader props are loaded on second render

Hey!
I love the project. Been looking for something like this to replace react-boilerplate's injectReducer and injectSaga.

I noticed that the DynamicModuleLoader renders its children on the first load
I forked the widgets example in this codesandbox: https://codesandbox.io/s/k9jo0kyzw5 and added a log statement in the mapStateToProps in src/widgets/hacker-news/. The log statement prints
screen shot 2019-02-18 at 9 29 31 pm

Is there a way to prevent the rendering of the child component until the modules are all loaded from DynamicModuleLoader? I use PropTypes in my project and a required prop will force me to make default values for my selectors as the state will not exist until the second render.

Browser freezes with redux dev tools open

When using redux-dynamic-modules my browser freezes and crashes whenever I try and open the redux debugger. If I remove dynamic module loader and re-implement using standard redux setup everything works fine. Anybody else having this issue? Renders this otherwise useful package useless to us.

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.