Giter VIP home page Giter VIP logo

dyo's Introduction

Dyo

Dyo

A JavaScript library for building user interfaces.

Coverage Size Licence NPM

Installation

  • Use a Direct Download: <script src=dyo.js></script>
  • Use a CDN: <script src=unpkg.com/dyo></script>
  • Use NPM: npm install dyo --save

Documentation

Documentation can be find on the website.

See the Getting Started page for a quick overview.

The documentation is divided into several sections:

You can improve it by sending pull requests to this repository.

Examples

Several examples can be found on the website. Here's one to get started:

import {h, render} from 'dyo'

function Example (props) {
	return h('h1', {}, 'Hello ', props.name)
}

render(h(Example, {name: 'World'}), 'body')

This will render a heading element with the text content "Hello World" into the specified target(the body element).

Comparison

The library is much alike React, so it's only natural that a comparison of the differences is in order; Which if successful might manage to highlight why it exists.

Re-parenting

The Portal component supports string selectors as targets. This presents an array of different possibilities with regards to isomorphic target references.

function Example (props) {
	return h(Portal, {target: 'main'}, 'Hello')
}

render(h(Example), 'body')

In addition to this โ€“ re-parenting is baked into portals. That is when a portals container is changed, instead of unmounting its contents and re-mounting them to the newly designated container we can instead move its contents without replaying destruction unmount operations that may discard valuable interface and component state.

In co-ordination with custom renderers, portals afford the opportunity to create atomic branch specific custom renderers. Imagine isolated declarative canvas renderers within a document renderer.

Promises

Promises(or thenables) are first class values. This affords authors the ability to render promises, directly await promises within effects and events, and delay unmounting.

render(props => Promise.resolve('Hello'), 'body')

function Example (props) {
	useEffect(async () => {
		// out of band updates in here
		// are also batched
		return async () => {
			// delays unmount until the animation
			// has completed
			return props.current.animate({}).finished
		}
	})
}

Callbacks

In an async world, public interfaces like render are not guaranteed to complete synchronously if a subtree happens to have async dependencies within it. A consequence of this will see more use cases for the optional callback arguments that this function accepts โ€“ in much the same way authors are afforded the ability to await on this central routine.

await render(props => Promise.resolve('Hello'), 'body')
Resources

In addition to other hooks, a resource allocation hook that can be used to fetch and cache resources.

function Example (props) {
	const resource = useResource(props => fetch('https://reqres.in/api/users'))
	return h('pre', {}, JSON.stringify(resource))
}
Async Server Rendering

Server side rendering supports the plethora of async primitives supported.

import {http} from 'http'
import {h, render, useResource} from 'dyo'

function Example (props) {
	const resource = useResource(props => fetch('https://reqres.in/api/users'))
	return h('pre', {}, JSON.stringify(resource))
}

http.createServer((request, response) => {
	return render(h('html', {}, h(Example)), response)
}).listen(8080)

License

Dyo is MIT licensed.

dyo's People

Contributors

0xflotus avatar askuzminov avatar chmln avatar gamtiq avatar gitter-badger avatar mcjazzyfunky avatar peterdavehello avatar thysultan 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  avatar  avatar  avatar

dyo's Issues

Diffing between static vdom-node and text-node fails

x = h('span');
setState = null;
Root = function() {
  setState = this.setState.bind(this);
  return h('div', this.state.showText ? 'test' : x);
};
Root.getInitialState = function() {return {showText: false};};

render(Root, $el = document.createElement('div'));
console.log($el);
setState({showText: true});
console.log($el);
setState({showText: false});
console.log($el);
<!-- Expected -->
<div><div><span></span></div></div>
<div><div>test</div></div>
<div><div><span></span></div></div>
<!-- Recieved -->
<div><div><span></span></div></div>
<div><div>test</div></div>
<div><div>test</div></div>

full page diff

The server side rendering example includes the entire page DOM
https://dio.js.org/api.html#server

However it is not possible to render to the document object.
What is the expected way to diff the <head> block?

the major use case is the <title> tag, but also having a dynamic manifest.json for marketplaces (e.g. clay.io (mobile))

add some tests

Some unit tests will prove every thing is work as expected and help us to contribute will PRs โญ

access DOM node in event callback

currently events are called with owner as this instead of the DOM node

I'd prefer unwrapped event callbacks, but if that's a deal-breaker passing the DOM node to the event handler is a reasonable alternative

e.g.

render = function() {
  h('a', {
    href: '/local'
    onclick: function(e) { router.go this.href }
    onclick: function(e, $$el) { router.go $$el.href } // alternate
  })
}

broken lifecycle behavior for function components

for function components, only one of didMount or willMount is ever called, depending on which was defined last

function render() {
  return h('div')
}
render.componentDidMount = function() { console.log('did mount') }
render.componentWillMount = function() { console.log('will mount') }
// 'will mount'
render.componentWillMount = function() { console.log('will mount') }
render.componentDidMount = function() { console.log('did mount') }
// 'did mount'

expected

// 'will mount'
// 'did mount'

possibly related, this is dead code
https://github.com/thysultan/dio.js/blob/70dbe849b701d484373fd10d1733157fe661f53d/src/Boundary.js#L78

Typescript Errors in Definition

https://github.com/thysultan/dio.js/blob/master/types/typescript.d.ts#L363

ERROR in $PATH/node_modules/dio.js/types/typescript.d.ts
(363,52): Cannot find name 'P'.

ERROR in $PATH//node_modules/dio.js/types/typescript.d.ts
(363,55): Cannot find name 'S'.
tsc -v
Version 2.6.2

tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
    "module": "esnext",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */

    "strict": true,                           /* Enable all strict type-checking options. */               /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    "noUnusedLocals": true,                /* Report errors on unused locals. */
    "noUnusedParameters": true,            /* Report errors on unused parameters. */
    "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */

    /* Module Resolution Options */
    "moduleResolution": "node",
    "jsx": "React",
    "jsxFactory": "dio.createElement"
  }
}

Support for "propTypes"?

Just a short question:
DIO does not have support for property validation (aka. "PropTypes"), does it?
(it seems that DIO version 3.4.0 did have some support for "propTypes")

[Proposal] Support web component constructor?

Given the following web component.

class AppDrawer extends HTMLElement {}

You could theoretically render it in the either one of the following ways.

Method 1.

// define localName
window.customElements.define('app-drawer', AppDrawer);
// render using localName
render(<app-drawer></app-drawer>)

Method 2.

// render using constructor
render(<AppDrawer />)

The second method does not work, and though the first method does, the second feels more natural coming from components as functions/classes. This issue asks the question of "I wonder if we should add support for the second".

Possible Implementations.

1. Autogenerate localName.

If the DOM renderer auto generates a localName for web components we can support both methods and insure that both the problem of duplicate defined localNames and undefined localNames does not occur, though this might mean some component names would have a prefix/suffix in their name in dev-tools.

2. new WebComponentClass

Since new WebComponentClass() generates a DOM node we could use this, but it's uncertain whether the different web-component polyfills support this pattern of creating a web-component and we might still run into the problem of name conflicts or undefined localNames, so preferably this would be wrapped in a try-catch to catch those scenarios.

Restrictions

Either method if implemented should be in such a way that custom renderers can employ their own heuristics for custom elements.

How about automatic reporting errors?

If I understood the errors handling section of the React documentation correctly it does not catch errors from event listeners. However, it seems Dio.js does catch those errors in order to display a proper stacktrace in the console logs, which is awesome, but it ends up swallowing the error, making it impossible to install a catch-all error to report them to some service such as Bugsnag, for example.

Dio.js should either allow us to provide an option to rethrow the exception after logging it, or to install a generic error handler or to add some hook in the component such as componentEventHandlerDidThrow or something like that.

What do you suggest as an approach to report such errors (since componentDidCatch is not called in those situations) to some errors monitoring service?

Nested rendering with children array broken

v8.2.3

setRootState = null;
setWrapperState = null;

Child = function() {
  return h('div', 'child');
};

Wrapper = function({children}) {
  setWrapperState = this.setState.bind(this);
  return h('div', children);
};

Root = function() {
  setRootState = this.setState.bind(this);
  return h('div', h(Wrapper, h(Child, ['xxx']))); // NOTE: non-empty child-array
};

render(Root, document.createElement('div'));
setRootState({x: 'root'});
setWrapperState({x: 'wrapper'});
TypeError: Cannot read property 'id' of undefined

undefined property values should be ignored

h('a', {href: undefined})
// got: <a href="undefined">
// expected: <a>

this is caused becuase of how setAttribute works

$a.setAttribute('href', undefined)
// <a href="undefined">

also null should probably be ignored as well

question: how to handle request response status

About .request, maybe I'm missing something, then and catch are working correctly but I never see err populated, always empty, and while I get the response object from then I can't check the server status which may return an application error (eg: 422 data validation failed).

Currently I'm using a workaround saving xhr from config: function(xhr) but I guess this is not how is supposed to work, what I'm missing?

[V8] [question] opaque DOM node embed

How can I embed a 3rd party DOM node within a vtree?
e.g. I want to embed a CodeMirror node

Editor = _=> h('div', h('textarea'))
Editor.componentDidMount = ($el) => CodeMirror($el.querySelector('div > textarea'))
Editor.componentWillUnmount = ($el) => CodeMirror.destroy($el.querySelector('div > textarea'))

The CodeMirror constructor hides the textarea and appends it's own dom tree to the parent node

<div>
  <div class="code-mirror"><div></div></div>
  <textarea style="display:none"></textarea>
</div>

[v8] [question] Partial <head> diff support?

Problem:
Third party libraries tend to like adding resources dynamically to <head> at run-time. Additionally, currently the initial diff re-writes resource tags causing re-requesting (e.g. <script src="xxx">)

Original Solution:
I wrote a custom diff for <head> which only diffed <link>, <meta> and <title> tags

Proposed Solution:
blank fragment placeholder, allow appending to DOM node

e.g.

<head>
  <title>xxx</title>
  h(BLANK_FRAGMENT)

then a library could append to <head> without altering diffing

I have no clue whether this makes sense. Another Idea I had was to mark original DOM nodes as editable (all new dio nodes would also be marked), then diff would ignore non-editable DOM nodes. (this doesn't fix re-requesting on initial diff)

Reference to component is set in wrong order

Hi, take a look at this example app: https://codesandbox.io/s/0x1xj6m60p

You'll notice that while both React, Inferno and NervJS set the reference to component in the right order while clicking on the "Second" button (null is logged before the new reference), both Dio.js and Preact seem to process them in the wrong order (new reference, then null).

When implementing a client-side routing while willing to keep a reference to the current app, it's very important that this order should work like React, Inferno and NervJS. Would you mind fixing this, please?

setState and state doesn't work

Hey, guys!

Nice work in this library!! But, I had played with it a little and I found a bug.

LIBRARY VERSION

7.1.0

PROBLEM

The state and setState aren't in sync.

EXPECTED

  • When the setState is called, it should update the state property and trigger the rendering again, if there are changes.

CURRENT BEHAVIOR

  • No matter how do you set the state using the setState, it will always contain an empty object as the state.

Consistent function naming, dio.curry

A curried function is a function that can be partialy applied and executes once the number of provided arguments is equal to the function arity, example:

var curried = curry(function(a, b, c){
    console.log(a + b + c)
}) 

curried(1)(2)(3)
curried(1, 2)(3)
curried(1)(2, 3)
// the three calls logs 6

AFAIK dio.curry does not returns a curried function, it returns a function wrapped with fixed predefined arguments. To avoid confusion the renaming should be taken in consideration. My proposal is:

  • dio.defer
  • dio.wrap
  • dio.listener
  • dio.partial

I prefer dio.defer dio.partial

Double unmount (and missing unmount) with cached static node

This was caused by upgrading from 8.0.0 -> 8.1.0

{h, render} = require 'dio.js'
A = -> h 'div'
A.componentDidMount = -> console.log 'mount A'
A.componentWillUnmount = -> console.log 'unmount A'

B = -> h 'div'
B.componentDidMount = -> console.log 'mount B'
B.componentWillUnmount = -> console.log 'unmount B'

setState = null
cachedState = null
Parent = ->
  setState = this.setState.bind(this)
  h('div', this.state.child)
Parent.getInitialState = -> cachedState or {child: h('div', A)}

setStateRoot = null
Root = ->
  setStateRoot = this.setState.bind(this)
  h('div',
    if this.state.isMounted then Parent else null)
Root.getInitialState = -> {isMounted: true}

render(Root, document.createElement 'div')
setState(cachedState = {child: h('div', B)})
setStateRoot({isMounted: false})
setStateRoot({isMounted: true})
setState({child: h('div', A)})
setStateRoot({isMounted: false})
# Expected
mount A
mount B
unmount A
unmount B
mount B
mount A
unmount B
unmount A

# Received
mount A
mount B
unmount A
unmount B
mount B
mount A
unmount B
unmount B

support error boundaries?

inspired by fiber, dio v5.2.0 might introduce error boundaries, this issue will document possible implementation details.

class Foo extends dio.Component {
    componentDidThrow (err) {
        switch (err.location) {
            case 'componentDidMount': return h('h1', 'something bad happened in did mount');
            case 'render': return h('h1', 'something bad happened in render');
        }
    }
    componentDidMount () {
       throw 'pawned!';
    }
    render () {
        return h('h1', 'Hello World');
    }
}

After componentDidMount throws, it will first render nothing from the Foo component and continue to the end of the stack at which point it will then re-try to render the Foo component, if it still fails it will then capture the error and pass it to componentDidThrow if it exists, if componentDidThrow returns something that can render(element/string/array) dio will render that else continue to render nothing. If componentDidThrow is not defined it fallbacks to the default error handler that prints a console.error of the error and continues to render nothing.

Dio caught an error thrown by "Foo", the error was thrown in "componentDidMount".

The object passed to componentDidThrow will have the shape

{
    from: 'Foo',
    location: 'componentDidMount',
    message: 'pawned!',
    stack: 'js stack trace...'
}

render, lifecycle methods and callbacks passed to setState and forceUpdate will fall within the areas that are supported by error boundaries.

support client and server async rendering

It will look something like

const Heading = h => ({
	async getInitialProps (props) {
		return {name: 'World'};
	},
	render ({name}) {
		return h('h1', 'Hello ' + name);
	}
});

dio.render(Heading, '#root');

when getInitialProps returns a promise/stream the component will fall through to async rendering.

Error loading dio 8 with Brunch

@thysultan ,
requiring dio 8 with brunch generates the following error:

Error: Cannot find module 'dio.js/dist/node' from 'dio.js/dist/umd.js'
Something went wrong trying to import the server module.

I don't use SSR so I can ignore the error, but it is annoying for my users.
Dio v7.x does not have this issue.

Anyway, this is a great library. Thanks for your work!

Text inside muicss Button is duplicated

Hi, I'm sorry but I can't find any online sandbox supporting aliases to provide you a link so that you could easily test it.

Basically, with webpack, one can add aliases, which can be quite useful when trying React libraries with React-compatible alternative libraries such as Dio.js, Inferno.js, Preact and NervJS. If you create aliases for both 'react$' and 'react-dom$' pointing to 'dio.js', then you should be able to run this example from the MUI-React documentation:

https://www.muicss.com/docs/v1/react/introduction

Just include the CSS as explained in the introduction and run their full example. It mostly works, but the button text is duplicated for some reason. It works fine with both React (of course) and inferno-compat aliases, so it's probably some tricky bug in Dio.js. I'd appreciate if you could figure out what's causing this behavior and fix it. I'd love to use Dio.js in my project, as it's more lightweight than Inferno.js and I also enjoy having more than one option regarding React alternatives. I tried Material UI before MUI, but not only Material UI is big but it also makes explicit use of the synthetic events API which are not supported by Dio.js (Inferno does support them, so it works with inferno-compat, but if I were able to use MUI with Dio.js, that would be very helpful).

I hope you have some time and interest in making it easy for Dio.js users to use existing React UI libraries through aliases in their webpack projects :)

Thanks for Dio.js :)

Hydration failure on consecutive text nodes

{h, hydrate} = require 'dio.js'
Root = ->
  h('div', 'abcabcabc', 'xxx')
$el = document.createElement 'div'
$el.innerHTML = '<div>buy now</div>'
hydrate Root, $el
Error: Failed to execute 'splitText' on 'Text': The offset 9 is larger than the Text node's length.
	    at getDOMQuery (build/tests.js:21897:14)
	    at commitQuery (build/tests.js:21029:4)
	    at commitMount (build/tests.js:20789:11)
	    at commitChildren (build/tests.js:20742:4)
	    at commitMount (build/tests.js:20804:3)
	    at commitMount (build/tests.js:20764:5)
	    at mount (build/tests.js:21616:3)
	    at mount (build/tests.js:21604:11)
	    at hydrate (build/tests.js:21580:3)
	    at Context.<anonymous> (build/tests.js:26814:12)

[V8] ~100% test coverage

How to add code coverage with istanbul:

npm i -D nyc
# npm i -D graceful-readlink
// package.json > "scripts"
"test": "nyc --reporter=lcov --reporter=text mocha --require script/test/index.js"

now when test is run, code coverage will print to console, with a detailed report available at

/coverage/lcov-report/index.html

e.g. getDefaultProps() is never hit by tests

'Github' typos

Consider supporting mixed case events.

I wanted to open this issue so folks using DIO know about it. There are a few similar bugs in other libraries.

DIO can listen to native DOM events dispatched from Custom Elements. However, it uses a heuristic to convert JSX event binding syntax into event names, and always lowercases the events. For example onFooUpdated={handleFoo} tells DIO to listen for an event called 'fooupdated'. This means DIO can support events with lowercase and kebab-case names, but not camelCase, PascalCase, or CAPScase events (e.g. 'URLchanged').
From https://custom-elements-everywhere.com/#dio-handling-events

Preact tracking bug - preactjs/preact#788
Polymer tracking bug - Polymer/polymer#4888
Stencil tracking bug - ionic-team/stencil#373

Feel free to close if you don't think this is an actual issue or you don't intend to work on it. The main objective of my tests is just to outline what will and won't work so developers can figure out best practices.

"forceUpdate" does not always update the view

Bug description (bug is to be found at least in V8.2.4 and V9.0.2):

There are rare cases where "forceUpdate" does not really update the view.
In those particular cases after calling "forceUpdate" the method "shouldComponentUpdate" is invoked before the intended view update, and if "shouldComponentUpdate" returns false then the view update will be cancelled.
The problem: After "forceUpdate" is called there should NOT be a "shouldComponentUpdate" check before rerendering, "forceUpdate" should ALWAYS update the view.

Those cases are quite exotic and a bit diffucult to explain - please check the component "DioCounterInfo" and "ReactCounterInfo" in the following demo to see what I mean:

https://jsfiddle.net/1q6whvye/

Please be aware that even if that use case seems really exotic and looks like kinda bad implementation, there are nevertheless real-world use cases where that bug matters - otherwise I would not have found it ;-)

Render errors should serialize to an empty string

class Component {
  componentDidThrow(err) { return err }
  render() {
    throw new Error('x')
  }
}
console.log(`${h(Component)}`)
// expected
''
// got
`<pre>{
  &quot;location&quot;: &quot;render&quot;,
  &quot;message&quot;: {}
}</pre>`

keyed benchmark?

hey @thysultan

was wondering if you were planning on submitting a keyed v6 or v7 implementation of js-framework-benchmark. curious how it would perform :)

Why not making it compatible with React.js?

Hi, I find it interesting that I can use the same code with React, Preact and Inferno by simply importing the equivalent h, render and Component from them. I'd love to be able to do the same with Dio.js, but it seems Dio's API is not compatible. For example, inside a component's render I'd have access to the props with this.this.props instead of this.props. Wouldn't you be interested in keeping the same compatibility layer in the basic API, just like Preact and Inferno do? This way, authors of React-like application can easily switch their VDOM implementation and compare them.

Question: JSX Support

I wonder if adding jsx syntax support (probably a babel/webpack/rollup plugin) would be interesting for those users who already like react-like libraries.

So I can write the Welcome component as

class Welcome {
	render() {
		return <h1>Hello ${this.props.name}</h1>;
	}
}

Any plans or work in progress?

v7.0.0 [new features]

v7.0.0 is a new version that will come out soon, this issue acts as a issue tracking on the progress including changes and new features that will come with it.

new features

  1. First class support for lazy loading components and stylesheets.
  2. Adds dio.fetch top level API
  3. Adds progress to http API dio.fetch('', {progress: (e) => {}}))
  4. Adds dio.module top level API.
  5. Improves coroutine components done rendering state.
  6. Removal of dio.request(options), in favour of fetch(url, options)

breaking changes

V7.0 will introduce a few breaking changes if something other than the high level api's createElement or h are being used to create virtual element this includes createFactory but excluding DOM, other than that nothing else should break.

1. Lazy Loading Components

First class support for lazy loading components will allow for the following asynchronous component loading pattens.

// Components/Bar/index.css 
& {
	color: red;
}
// Components/Bar/index.js
class Bar extends Component {
	render ({message}) {
		return h('h1', message);
	}
}

export default Bar;
// entry.js
const {fetch, Component} = dio;

class Slot extends Component {
	stylesheet () {
		return fetch('Components/Bar/index.css');
	}
	render () {
		return fetch('Components/Bar/index.js', {
                        body: {message: 'Hello World'},
			progress: h('h1', 'Loading Component...')
		})
	}
}

dio.render(Slot);

When render is called Slot progress element <h1>Loading Component</h1> will mount. After the index.js file is loaded into the browsers VM and the exported component in index.js replaces the progress element on the other hand index.css is loaded, name-spaced and added to the page. If a function is passed as opposed to a virtual element as the value of a property progress on the optional second argument of fetch() will expose the ProgressEvent object as a single argument.

2. Fetch

dio.fetch will mimic for the most part the window.fetch, the introduction of this API also introduces context aware request that makes returning a http request object from an render method.

3. Fetch/Request progress

fetch('foo.js', {
    progress: ({loaded, total, timeStamp}) => {
        console.log(total - loaded, timeStamp);
    }
})

4. Modules

dio.module is the low-level module loader that fetch uses when returned from a render method.

// entry.js
module('foo.js').then((foo) => {
    foo.add(1, 2);
})

// foo.js
const add = (a, b) => a + b;
export {add}

If you wanted to transpile modules on the fly before consumption dio.module also allows you to register one via dio.module.transpile = fn

5. Improve Coroutines "done" state

This may be a feature or bug depending on how it's view but currently when a coroutines component reaches a done state it is unmounted on the next render. v7.0.0 will change this behavior to prevent unmounting when done and the subsequent .next() returns nothing.

[intent to implement] Timeout, Suspense

Given DIO's ability to render Promises, the mentioned components may server as good abstractions for these.

React currently uses a combination of componentDidCatch and throw for the control flow of this, we may be able to do the same or directly use Promises since DIO is able to render them.

Hopefully we can try to implement a POC and see along the way if anything needs to change with the internal implementation of componentDidCatch to make this work.

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.