acdlite / recompose Goto Github PK
View Code? Open in Web Editor NEWA React utility belt for function components and higher-order components.
License: MIT License
A React utility belt for function components and higher-order components.
License: MIT License
There are situations at almost all controls I've wrote when I need to hold some state but this state isn't React or Flux state. Because I don't want additional rerender.
For example:
_onMouseEnter(poly) {
clearTimeout(this.mouseLeaveTimeoutHandle_);
onHoveredChange(poly);
}
_onMouseLeave( /* poly */ ) {
this.mouseLeaveTimeoutHandle_ = setTimeout(
() => onHoveredChange(null),
1000 / 60
);
}
Here I use this.mouseLeaveTimeoutHandle_
to prevent rerender if Mouse enter new object.
Sometimes such state
used as cache, sometimes to support imperative DOM calls.
May be recompose needs something like withState
but with getter
functions support and without setState
calls?
(For such state Getter Setter functions (or one function) are passed through props, not a value)
It's easy for any class component to get props
in any event callback,
having reference to callback not change across render calls.
class Blabla ... {
onClick = () => {
const props = this.props;
... do Some work based on props;
}
render() {
// this.onClick is same every render
return <BlaBla onClick={this.onClick} />;
}
}
mapProps cause callback refs to change at every render call (if I need to have access to props
inside
callback)
Like
mapProps(props => {
...props,
// reference to onClick here changed at every render call
onClick() {
// use props here, also i can't call other methods defined here
}
}
May It's good to create something like bindToProps HOC,
onClick(props, args) {
}
bindToProps({onClick})
...
Because every time I start to write stateless component I need to write something like
<BlaBla onClick={(...args) => onClick(props, ...args) } />
And I dislike the Idea that every time BlaBla receives a new function reference and lost some of his shouldComponentUpdate optimization.
If I have a component which should be able to return markup on the server but then hook into a browser API after being mounted I don't believe lifecycle()
will work because setup()
is called in the constructor and will throw when instantiated on the server.
A work-around would be to create an abstraction over setting up the component's client-side behavior which is just a no-op on the server, but React already provides componentDidMount()
for this case and so seems less complex and more idiomatic.
Is there a plan for allowing lifecycle setup within componentDidMount()
instead of the constructor?
While working with mapPropsOnChange
recently we noticed that this.props
get spread over computed props
.
https://github.com/acdlite/recompose/blob/master/src/packages/recompose/mapPropsOnChange.js#L24
It appears the original plan was to spread computed props last?
#60 (comment)
Example:
I create an items
prop with mapPropsOnChange
mapPropsOnChange(['thing'], ({thing}) => ({items: thing.count()}))
but if items
was already a prop being passed down the new computed prop of items
will get overwritten by this.props.items
.
I would expect my outputted computed props to be what gets passed down.
Let me know what you think, and I could get a PR in with tests this week.
Because withProps
using stateless components, connect
attaching ref
to child component, and react
doesn't allow attach ref
to stateless components.
createSpy()
is a temporary hack I came up with until a proper solution for testing function components emerged. I would really like to get rid of it.
Once there is stable, widely-used testing framework that supports functional components, let's remove createSpy()
. Candidates:
Hello and a quick thanks for the library! I've been enjoying it a lot.
I noticed that the withProps
function is documented as only accepting an object, but seems to be written to also accept a function:
Docs:
withProps()
withProps(
props: Object,
BaseComponent: ReactElementType
): ReactElementType
Src:
const withProps = (input, BaseComponent) => {
let getProps
const props = isFunction(input)
? input(getProps)
: input
return ownerProps => {
getProps = () => ownerProps
return createElement(BaseComponent, {
...ownerProps,
...props
})
}
}
Secondly, I don't think the function form will work as expected because at the time of the function call, getProps
is still undefined
. If we were to move it below the getProps
definition I think it'd work:
const withProps = (input, BaseComponent) => {
let getProps
let props
return ownerProps => {
getProps = () => ownerProps
props = isFunction(input)
? input(getProps)
: input
return createElement(BaseComponent, {
...ownerProps,
...props
})
}
}
I'd be happy to open up a PR with some fixes but just wanted to check first to make sure it was the intended idea.
I love this.
My only question about using function components, how do you specify propTypes
? For documentation purposes chiefly, but they also help catch stupid mistakes.
This works but it doesn't look that great:
const Text = ({ children }) =>
<p>{children}</p>
Text.propTypes = { children: React.PropTypes.string };
Text.defaultProps = { children: 'Hello World!' };
I saw that you use Flow type notation in the documentation. Is that a possible route? Replacing propTypes with Flow annotations entirely?
lifecycle(
setup: (component: ReactComponent) => void,
mount: (component: ReactComponent) => void,
teardown: (component: ReactComponent) => void,
BaseComponent: ReactElementType
): ReactElementType
Add mount
option to lifecycle
that calls your function during componentDidMount
. This will allow use for isomorphic/universal apps when you only want things ran on client and not on server.
Let me know what you think. I could probably get a PR in this week.
From my first impression I would like to use it to replace my old lil Flux. Is it going to be developed like that?
I have this pattern all over my codebase:
const ComponentA = React.createClass({
propTypes: {
id: PropTypes.string,
},
contextTypes,
getInitialState() {
return {};
},
componentDidMount() {
http.get(this.context.rootUrl + "SomeAPI", {id: this.props.id})
.then(config => {
if (this.isMounted())
this.setState({data});
});
},
render() {
return this.state.data
? (<ComponentB {...this.props} {...this.state.data}/>)
: (<Spinner/>);
}
});
A component, such as ComponentA, has to make an ajax call on mount, and then pass that data to another component on completion. I'm imagining a HOC signature that looks something like this:
onMount(
getData: (props: Object, context: Object) => Promise,
BaseComponent: ReactElementType
): ReactElementType
I tried to use the branch
function for 2 hours now, I can't figure out what I'm doing wrong. I'm trying to render a Loader if some props are missing, or the Page component. That's exactly what is done in the docs.
// I create a stateless component as always
const Page = ({ title }) => {
return (
<h1>{title}</h1>
)
}
// I create my Loader component
const Loader = () => {
return (
<span>Loading ...</span>
)
}
// Then, here comes the branch function, to render the relevant one
export default branch(
props => !! props.title,
renderComponent(Page),
renderComponent(Loader)
)
I keep getting ReactCompositeComponent.js:587 Uncaught TypeError: inst.render is not a function
Am I doing something wrong ?
What's returned from the branch
function is a function names PartialFunc
from createHelper.js
PS : I'm using the version 0.15.0
Does the library work with react-native?
React 15.0.0-rc1 add a new warning.
recompose seems touch key from props, so this warning shows up
key
is not a prop. Trying to access it will result inundefined
being returned. If you need to access the same value within the child component, you should pass it as a different prop.
I have a component structured something like:
const nothing = () => createSink(() => null)
const MyComponentContainer = branch(
props => props.some_flag,
withProps(...),
nothing)(MyComponent)
Unfortunately testing this with ReactShallowRenderer
seems a bit tough, here's the render result:
{ '$$typeof': Symbol(react.element),
type: [Function: Sink],
key: null,
ref: null,
props: { some_flag: false },
_owner: null,
_store: {} }
I have no idea what kind assertion to make to determine whether this is in fact the "nothing" result.
Add childProps to propsMapper call here
https://github.com/acdlite/recompose/blob/master/src/mapPropsOnUpdate.js#L19
Or allow additional check
Sometimes i need to do additional checks to decide do i need to recalculate props or can return previous value.
For example
@mapPropsOnUpdate(
['a', 'b'],
(props) => {
if (a<b) { // it can be computationally intensive check
return {...props, result: I_WANT_TO_RETURN_PREV_RESULT}
}
return {...props, result: calcNewResult(props)}
}
with childProps it will be easy
@mapPropsOnUpdate(
['a', 'b'],
(props, childProps) => {
if (a<b) { // it can be computationally intensive check
return {...props, result: childProps.result}
}
return {...props, result: calcNewResult(props)}
}
First of all thank you for open source this amazing library!
I've been using Flux for many projects (Alt, Redux, NuclearJS, Baobab).
I like Flux, but, at least for me, I don't think it's fun to write when project grows. The main reason is the boilerplate (it's just personal taste, I know that some people like boilerplate, also I know I can reduce boilerplate, anyway...).
I want to know if I can use Recompose to "mimic" some aspects of Relay.
My idea is to add data fetching inside containers and pass it to the component with "withState".
For state that need to be shared across all components I'll create an AppContainer (withState('usersOnline', 'getUsersOnline', [])
, withState('loggedUser', 'getLoggedUser', { isLoading: false, data: {}, error: null })
), then I'll create subcontainers, for example NotificationContainer (withState('notifications', 'getNotifications', [])
).
Do you think I can proceed this way?
I'm using withState to manage the value of a controlled input. Here's how i'm using it:
import { compose, withState, mapProps } from 'recompose';
const MyComponent = ({
originalTitle,
inputOnChange,
title
}) => {
return (
<div>
<input type="text" value={ title } onChange={ inputOnChange }/>
</div>
);
};
export default compose(
withState('title', 'changeTitle', (props) => props.originalTitle),
mapProps((props) => _.assign(props, {
inputOnChange: (e) => props.changeTitle(() => e.target.value)
}))
)(MyComponent);
And the error i'm getting is:
Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property `target` on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist(). See https://fb.me/react-event-pooling for more information.
Uncaught TypeError: Cannot read property 'value' of null
Now, I read about Event Pooling, and saw some recommendations to use event.persist(), but I couldn't figure out how to use it in this setup.
Any help will be greatly appreciated!
Thanks
We finally made it to React 14, so I've gotten to use recompose in a large app for about a week now. Per the twitter request, here's a running list of thoughts...all of which I believe could be addressed through documentation. The functionality itself is amazing π² π² π² . I'm happy to create PRs if these seem reasonable.
onlyUpdateForPropTypes
initially looks like an obvious win when combined with something like eslint-plugin-react's prop-types rule, but you can get yourself into trouble if you're passing your props through to children components using destructuring<ChildComponent {...this.props}/>
// this will pass lint, but means your child component wil not update as expected
// if you wrap your component in onlyUpdateForPropTypes
ctrl+f api
a dozen times a day.withContext
and getContext
is super powerful, but it took me a bit to figure out. For instance, I end up propagating props that originated in my context. Perhaps a diagram showing the wrapping classes and how the context/props are changed at each level. In general, context is sort of hard to reason about, so all the hocs that deal with it could use a couple examples imo.When a FORM element submit event occurs, you need to return false and call event.preventDefault(). Otherwise the form will attempt to submit the form in the background before processing other event subscribers.
The FuncSubject from https://github.com/fdecampredon/rx-react allows developers to define an immediate callback, which allows developers to prevent form submission. I'll can create a pull-request with the change.
Great work on this project, and your work in react-rx-component. Quite a beautiful way to build components.
Hi,
I wanted to build a container creation utility for React few weeks ago. I searched for an existing one, but I couldn't figure out a one.
I didn't find this one.
So, I created a one on my own called react-komposer and I just discovered this one.
Surprisingly, core APIs are just like the same.
Just wanted to mention this. Feel free to close this issue.
Although it has the same effect, using the defaultProps() HoC is not the same as setting the static defaultProps property directly on the component.
Intriguing, but unsatisfying. I think this statement merits a word on how it's not the same.
ERROR in ./~/rx-recompose/observeProps.js Module not found: Error: Cannot resolve module 'recompose/createHelper'
npm ERR! peerinvalid Peer [email protected] wants recompose@^0.8.0
createHelper
is only exists in 0.9.0 onwards.
In production, createHelper
is set to lodash's curry
here, which has signature:
curry(func, arity)
.
In development, it uses a custom implementation here with signature:
curry(func, helperName, arity, setDisplayName)
Note the different arity argument position.
createHelper
is used to create setStatic
here with the arity as the 3rd argument. This works fine in development, but in production, Lodash returns the function without actually implement currying.
setStatic
, expecting to be curried, is called with a single argument here. This works fine in development but throws in production because it tries to access a key on an undefined variable.
This all happens during library setup, so even just including recompose
in production throws the cryptic error: Uncaught TypeError: Cannot set property 'propTypes' of undefined
.
There seems to be a dependency issue, possibly related to babel-relay-plugin
.
If you do a fresh clone
and npm install
then npm test
you get a lot of these errors:
Module build failed: ReferenceError: Unknown plugin "./src/packages/recompose-relay/babelRelayPlugin" specified in "base" at 0
any thoughts? it is currently blocking all PR's
My native language is not English, but I assume that depdendentPropKeys
should be written as dependentPropsKeys
. Am I right?
I'm considering dropping the automatic currying of Recompose helpers.
recompose/withProps
, the code that implements currying is larger than the code needed to implement withProps()
itself.Instead, I propose that we remove automatic currying and instead move toward an API like React Redux's connect()
.
// Before: all these forms work
helper(a, b, c)(BaseComponent)
helper(a, b, c, BaseComponent)
helper(a)(b)(c)(BaseComponent)
// etc.
// After: only this form
helper(a, b, c)(BaseComponent)
Note that this is still compatible with compose()
What do you think?
I have:
os: OSX Captain
node: v0.12.2
npm: 2.10.1
I run
npm install
npm run test
output
Chrome 46.0.2490 (Mac OS X 10.11.1) ERROR
Uncaught Error: Cannot find module "mock-modules"
at /Users/ice/temp/recompose/tests.webpack.js:143093 <- webpack:///src/packages/recompose-relay/~/react/~/envify/~/jstransform/src/__tests__/jstransform-test.js:19:0
Static Class Properties compile down to use of Object.defineProperty
which breaks in ie8. I'm happy to do the refactoring work to do things the (unfortunately less pretty) oldschool way.
Let me know if this sounds good - otherwise I'll have to fork :(
Sorry to ask you this directly but would you mind clarifying a bit of your example?
mapProps(({ setCounter, ...rest }) => ({
increment: () => setCounter(n => n + 1),
decrement: () => setCounter(n => n - 1),
...rest
}))
So far I have this when translated to ES5 by hand.
mapProps(function({setCounter: setCounter, /* ...rest??? */})) {
return {
increment: function() { return setCounter(n => n + 1) },
decrement: function() { setCounter(n => n - 1) },
// ...rest?????
}
})
I have three questions.
...
will spead the values in rest
into the object but I'm really confused as to where rest
comes from.I don't think many people will find it easy to understand what this example does. Might want to cool it with the ({(({}) => ({}))})
and some of the more advanced ES2015 features.
Many thanks.
The idea is to create 'invariant like' HOC to check properties at dev builds.
The signature:
invariant(
propsValidator: (ownerProps: Object) => Bool,
message: String,
BaseComponent: ReactElementType
): ReactElementType
Realization example (uses invariant lib):
import invariant from 'invariant';
import createHelper from 'recompose/createHelper';
import createElement from 'recompose/createElement';
const invariantHOC = (props2Condition, message, BaseComponent) =>
props => (
invariant(props2Condition(props), message),
createElement(BaseComponent, props)
);
export default createHelper(invariantHOC, 'invariant');
But may be for performance reasons instead of invariant behavior, fully throw away this checks at release builds.
What are you think?
When using observeProps, the props stream uses only the initial prop values for the first render.
In my case, I am using Recompose.lifecycle to load or fetch some cached data.However when I had a cached value, ie WORLD
, the template was still rendering with the default value HELLO
SmartFooTemplate = Recompose.compose(
observeProps( (props$) ->
foo$ = new Rx.BehaviorSubject("HELLO")
return Rx.Observable.combineLatest(
props$, foo$
(props, foo) ->
Object.assign {},
props
foo:foo
foo$:foo$
)
)
Recompose.lifecycle(
(self) ->
foo$.onNext('WORLD')
(self) ->
#Stuff I need to run when the component is unmounted.
)
)
DumbFooTemplate = React.createClass
render: ->
@props.foo # = 'HELLO'
@props.foo$.value #= 'WORLD'
let ContainerComponent = onWillReceiveProps(..., BaseComponent);
ContainerComponent = mapProps(..., ContainerComponent);
ContainerComponent = withState(..., ContainerComponent);
I was thinking it is valid JS syntax since the dots look exactly like spread operators. Maybe substitute them with /**/
comments would be better.
great library! So, I had been doing prop types, at least with stateless functions, like so:
const component1 = (props) => <div {...props} />;
component1.propTypes = { ... };
export default component1;
Which looks ugly. Maybe it's even too simple for this lib, but a withPropTypes could look like
const withPropTypes = curry((propTypes, component) => component.propTypes = propTypes);
Would still support non-stateless components while fitting nicely in the final compose.
const eventHandler$ = createEventHandler();
const subscriptionA$ = eventHandler$
.map(x => x + 2)
.do(x => console.log('A', x))
.subscribe();
const subscriptionB$ = eventHandler$
.map(x => x * 2)
.do(x => console.log('B', x))
.subscribe();
eventHandler$(3);
// Outputs:
// B 6
It only runs on the last subscriber, Is this an expected result?
Is that safe to do so?
const List = ({ items }) => (
<ul>
{items.map(item => <EnhancedItem item={item} />)}
</ul>
);
It will returns props
is undefined
.
Per react docs, it is expected that a context will be provided to a stateless functional component: https://facebook.github.io/react/docs/context.html#referencing-context-in-stateless-functional-components
I'm not sure if there's another "point of failure" aside from createElement for this behaviour not being supported by recompose right now, but it seems liek the sort of thing that should be supported.
Personally, I love the getContext helper and am using it in production, but I think it's important that helpers don't strictly enforce the "context as props" model and support the idiomatic React behaviour as well.
Happy to do the work on this if you think it gels with the project vision/opinions - let me know what you think
In withState
if stateUpdaterName
and stateName
are already defined in the props, pass props only here.
(without local updater and value.)
It allows to create controlled and uncontrolled components
Like
Component source
@withState('value', 'onChange', 0)
export default MyInput extends .... {
...
this.props.onChange(newValue);
...
}
Uncontrollable usage
<MyInput />
Controllable usage
<MyInput value={0} onChange={(newVal) => this.setState(newVal)} />
PS:
As I understand it can be done with branch
now.
These two private/util methods are really useful. It might be nice to either publish them as separate libraries on npm or expose them to consumers of recompose. Seems to me that people wanting to create their own helpers wont be a rare case, and these utilities are a huge help in that process.
Love the work you're doing on this.
Would it makes sense within the context of this library to provide helpers for rendering different components based on props?
For instance conditional()
could work like branch()
but instead of applying left/right HOC to the base component, it would render base component if test returns true and null if false.
Or switch()
, which would get an array of objects: { test: (props: Object) => boolean, component: Class<ReactComponent> }
and renders the first one that passes it's test. Base component could act as the default
in switch statements.
I use something similar to the above on my current project and would be happy to take a crack at a PR for recompose if this is something that makes sense to you.
This would be a helper that takes a function component and wraps it in a class. This can be used as a fallback for libraries that need to add a ref to a component, like Relay.
render()
, rather than creating a new element from it.propTypes
, contextTypes
, defaultProps
, and displayName
to the new class component.This would be a good first issue for anyone who would like to contribute.
recompose does not allow to use most used pattern similar to mapPropsOnChange
What if I need to create computationally intensive work only if some props is changed, but pass other props as is. So I get all props online, and compute results of intensive tasks only when it needed.
For example I have property x
and data
, I need to make some intensive calculus if data
changed but also I need to get current version of x
in my component. With mapPropsOnChange
I get the value of x
on the moment data
has changed. But every time I use this pattern I need new x
values.
This could be solved creating a HOC based on mapPropsOnChange
but changing this line
https://github.com/acdlite/recompose/blob/master/src/packages/recompose/mapPropsOnChange.js#L23
on this
return createElement(BaseComponent, {...this.props, ...this.childProps})
What are you think about
HOC with name and signature
withPropsOnChange(
depdendentPropKeys: Array<string>,
propsMapper: (ownerProps: Object) => Object,
BaseComponent: ReactElementType
): ReactElementType
console.log('testA', shallowEqual(['a'], ['a']));
console.log('testB', shallowEqual([1], [1]));
console.log('testC', shallowEqual(
{ a: 1 },
{ a: 1 }
));
console.log('testD', shallowEqual(
{ a: [1] },
{ a: [1] }
));
console.log('testE', shallowEqual(
{ a: ['a'] },
{ a: ['a'] }
));
Above codes will output:
testA true
testB true
testC true
testD false
testE false
I can't tell if the library is abandoned or not, but the broken peerDependencies are preventing me from using npm shrinkwrap.
This idea comes from Pete Hunt's jsxstyle: a helper to partially apply props to a component.
Here's a rough sketch of what it could look like for a stateless base component:
import omit from 'lodash/object/omit';
const applyProps = (partialProps, baseComponent) => {
const NewComponent = (moreProps, context) =>
baseComponent({ ...partialProps, ...moreProps }, context);
NewComponent.propTypes = omit(
baseComponent.propTypes,
key => key in partialProps
);
NewComponent.defaultProps = baseComponent.defaultProps;
return NewComponent;
};
And that might not be significantly different from this:
const applyProps = (partialProps, baseComponent) => {
const NewComponent = (moreProps, context) =>
baseComponent(moreProps, context);
NewComponent.propTypes = baseComponent.propTypes;
NewComponent.defaultProps = {
...(baseComponent.defaultProps || {}),
...partialProps
};
return NewComponent;
};
There is a minor correction in recompose/docs/API.md.
At https://github.com/acdlite/recompose/blob/master/docs/API.md#flattenprop, signature reads as renameProps( propName: string, BaseComponent: ReactElementType ): ReactElementType
While, it should be
flattenProp( propName: string, BaseComponent: ReactElementType ): ReactElementType
renameProps should be replaced with flattenProp.
I am new to this git environment, so don't know how to create a pull request. (Tried to read the github help for that, but did not get what do they mean by 'upstream branch' and 'your branch'. Also, what I think is, we need to repair the doc in 'master' branch itself. But github does not allow pull requests in 'master' branch.
Some developers I work with dislike that recompose
creates HOCs on each operation, so the tree in react tools is too deep.
As an example:
This code
https://github.com/istarkov/google-map-clustering-example/blob/master/src/GMap.js#L57-L126
The real examples we have at work has more deeper trees. (I does not use react tools at work, but others use it a lot)
And Yes I know that I can combine here 3 call to withState
into one or/and mapProps..
but this affects code readability for me.
I think that some of that multiple calls can easily (or not ;-)) be combined at compose level, as some optimization operation.
For example sequential calls to mapPropsOnChange
can be combined into one HOC automatically and etc....
May be it's too early to talk about this, but it's just an opinion of some developers.
At @taskworld, when we write components that communicate with the store upon mounting, we must do it in three different places: componentDidMount
, componentWillUnmount
, and componentDidUpdate
. For example:
var MessagesContainer = React.createClass({
propTypes: {
threadId: React.PropTypes.string.isRequired,
},
componentDidMount () {
this.subscription = subscribeToThread(this.props.threadId)
},
componentDidUpdate (lastProps) {
if (lastProps.threadId !== this.props.threadId) {
if (this.subscription) this.subscription.unsubscribe()
this.setState(this.getInitialState())
this.subscription = subscribeToThread(this.props.threadId)
}
},
componentWillUnmount () {
if (this.subscription) this.subscription.unsubscribe()
},
// ...
})
What if a component can reject prop changes?
When the threadId
changes, the old component that subscribes to the old thread is simply unmounted, and the new one with the new threadId is mounted in its place.
With that, we donβt need to handle the change in threadId
anymore:
var MessagesContainer = React.createClass({
propTypes: {
threadId: React.PropTypes.string.isRequired,
},
componentDidMount () {
this.subscription = subscribeToThread(this.props.threadId)
},
componentWillUnmount () {
if (this.subscription) this.subscription.unsubscribe()
},
// ...
})
Turns out it is possible with the special key
prop in React:
<MessagesContainer threadId={threadId} key={threadId} />
Now the MessagesContainer
will be replaced instead of having props sent to it. Just what I want. However, other people reviewing my code may not understand why I need to put a key
prop there.
Instead of relying on the users of MessagesContainer
to specify the key
prop to ensure correct subscribe/unsubscribe behavior, we can simply wrap MessagesContainer
in a higher-order component which automatically adds the key to the wrapped component.
This is our implementation of keyed
.
function keyed (propsToKey) {
return function createKeyedComponent (Component) {
const KeyedComponent = React.createClass({
render () {
return <Component {...this.props} key={propsToKey(this.props)} />
},
})
return KeyedComponent
}
}
And here is how to use it:
export default keyed(props => props.threadId)(Messages)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.