GithubHelp home page GithubHelp logo

riot / route Goto Github PK

View Code? Open in Web Editor NEW
211.0 9.0 40.0 2.05 MB

Simple isomorphic router

License: MIT License

JavaScript 85.60% Riot 14.40%
route router riotjs components minimal simple isomorphic

route's Introduction

Riot Router

Route logo

Build Status Code Quality NPM version NPM downloads MIT License Coverage Status

Simple isomorphic router

The Riot.js Router is the minimal router implementation with such technologies:

  • compatible with the DOM pushState and history API
  • isomorphic functional API
  • erre.js streams and javascript async generators
  • rawth.js urls parsing

It doesn't need Riot.js to work and can be used as standalone module.

For Riot.js 3 and the older route version please check the v3 branch

Table of Contents

Install

We have 2 editions:

edition file
ESM Module index.js
UMD Version index.umd.js
Standalone ESM Module index.standalone.js
Standalone UMD Module index.standalone.umd.js

Script injection

<script src="https://unpkg.com/@riotjs/[email protected]/index.umd.js"></script>

Note: change the part x.x.x to the version numbers what you want to use: ex. 4.5.0 or 4.7.0.

ESM module

import { route } from 'https://unpkg.com/@riotjs/route/index.js'

npm

$ npm i -S @riotjs/route

Download by yourself

Documentation

With Riot.js

You can import the <router> and <route> components in your application and use them as it follows:

<app>
  <router>
    <!-- These links will trigger automatically HTML5 history events -->
    <nav>
      <a href="/home">Home</a>
      <a href="/about">About</a>
      <a href="/team/gianluca">Gianluca</a>
    </nav>

    <!-- Your application routes will be rendered here -->
    <route path="/home"> Home page </route>
    <route path="/about"> About </route>
    <route path="/team/:person"> Hello dear { route.params.person } </route>
  </router>

  <script>
    import { Router, Route } from '@riotjs/route'

    export default {
      components { Router, Route }
    }
  </script>
</app>

You can also use the riot.register method to register them globally

import { Route, Router } from '@riotjs/route'
import { register } from 'riot'

// now the Router and Route components are globally available
register('router', Router)
register('route', Route)

Router

The <router> component should wrap your application markup and will detect automatically all the clicks on links that should trigger a route event.

<router>
  <!-- this link will trigger a riot router event -->
  <a href="/path/somewhere">Link</a>
</router>
<!-- this link will work as normal link without triggering router events -->
<a href="/path/to/a/page">Link</a>

You can also specify the base of your application via component attributes:

<router base="/internal/path">
  <!-- this link is outside the base so it will work as a normal link -->
  <a href="/somewhere">Link<a>
</router>

The router component has also an onStarted callback that will be called asynchronously after the first route event will be called

<router onStarted="{onRouterStarted}"></router>

Route

The <route> component provides the route property to its children (it's simply a URL object) allowing you to detect the url params and queries.

<route path="/:some/:route/:param"> {JSON.stringify(route.params)} </route>

<route path="/search(.*)">
  <!-- Assuming the URL is "/search?q=awesome" -->

  {route.searchParams.get('q')}
</route>

Each <route> component has its own lifecycle attributes in order to let you know when it gets mounted or unmounted.

<app>
  <router>
    <route path="/home"
      on-before-mount={onBeforeHomeMount}
      on-mounted={onHomeMounted}
      on-before-update={onBeforeHomeUpdate}
      on-updated={onHomeUpdated}
      on-before-unmount={onBeforeHomeUnmount}
      on-unmounted={onHomeUnmounted}
    />
  </router>
</app>

Standalone

This module was not only designed to be used with Riot.js but also as standalone module. Without importing the Riot.js components in your application you can use the core methods exported to build and customize your own router compatible with any kind of frontend setup.

Depending on your project setup you might import it as follows:

// in a Riot.js application
import { route } from '@riotjs/route'

// in a standalone context
import { route } from '@riotjs/route/standalone'

Fundamentals

This module works on node and on any modern browser, it exports the router and router property exposed by rawth

import { route, router, setBase } from '@riotjs/route'

// required to set base first
setBase('/')

// create a route stream
const aboutStream = route('/about')

aboutStream.on.value((url) => {
  console.log(url) // URL object
})

aboutStream.on.value(() => {
  console.log('just log that the about route was triggered')
})

// triggered on each route event
router.on.value((path) => {
  // path is always a string in this function
  console.log(path)
})

// trigger a route change manually
router.push('/about')

// end the stream
aboutStream.end()

Base path

Before using the router in your browser you will need to set your application base path. This setting can be configured simply via setBase method:

import { setBase } from '@riotjs/route'

// in case you want to use the HTML5 history navigation
setBase(`/`)

// in case you use the hash navigation
setBase(`#`)

Setting the base path of your application route is mandatory and is the first you probably are going to do before creating your route listeners.

DOM binding

The example above is not really practical in case you are working in a browser environment. In that case you might want to bind your router to the DOM listening all the click events that might trigger a route change event. Window history popstate events should be also connected to the router. With the initDomListeners method you can automatically achieve all the features above:

import { initDomListeners } from '@riotjs/route'

const unsubscribe = initDomListeners()
// the router is connected to the page DOM

// ...tear down and disconnect the router from the DOM
unsubscribe()

The initDomListeners will intercept any link click on your application. However it can also receive a HTMLElement or a list of HTMLElements as argument to scope the click listener only to a specific DOM region of your application

import { initDomListeners } from '@riotjs/route'

initDomListeners(document.querySelector('.main-navigation'))

route's People

Contributors

aadilhasan avatar agersant avatar cognitom avatar damusix avatar dependabot[bot] avatar dutradda avatar geonanorch avatar ggergo74 avatar gianlucaguarini avatar gpoitch avatar kiritoxf avatar lucidtech avatar lukasdrgon avatar mouvedia avatar raphaelmerx avatar tipiirai 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

route's Issues

route.query() not working as expected when using # base

When using # as the base, route.query() for these URLs is not behaving correctly:

  • index.html?param=xyz#/search => { param: "xyz#/search" }
  • index.html?param=xyz#/search?q=keyword => { param: "xyz#/search?q=keyword" }

Where ?param=xyz are query params for the server rather than the router.

It's not entirely clear how it should behave. The docs don't address it and the specs only test with '/' base. My expectation is that if using a # base, the router should only consider query params after the #. Which would look like this:

  • index.html?param=xyz#/search => {}
  • index.html?param=xyz#/search?q=keyword => { q: "keyword" }

When using '/' as the base, the issue doesn't exist because there's only one set of query params which is shared between server and router.

I didn't manage to write a spec to show this failing because the code behaves differently when running in the test suite (it doesn't use location.href).

Roadmap and todos

See also the discussion on riot/riot#1063.

v2.0.0

v2.3.0

  • support HTML5 history API
  • base url option: router.base('/foo')
  • click event override: to avoid page reloading
  • url match: router('/bar/*', function(id) { ... }) (allow only wild card)
  • 2-4x smaller than page.js
  • documentation
  • 100% coverage - now 99% Thanks! @GianlucaGuarini

Any feedback is appreciated ๐Ÿ˜„

Cannot pass options to routed tags

Hello

I created a basic app with Riot 3.1.0, and the latest router (I built it from sources, as riot+route.min.js doesn't seem to be available on jsdelivr).

The app contains three files:

hello.tag:

<hello>
  <span>Hello { opts.name }!</span>
</hello>

app.tag:

<app>
    <router>
      <route path="">
        <hello name={ name }></hello>
      </route>
    </router>
    <script>
        this.name = "World"
    </script>
</app>

index.html:

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>

    <app></app>

    <script type="text/javascript" src="riot+compiler.min.js"></script>
    <script src="route+tag.min.js"></script>
    <script type="riot/tag" data-src="./app.tag"></script>
    <script type="riot/tag" data-src="./hello.tag"></script>

    <script type="text/javascript">
      riot.mount('app')
    </script>

  </body>
</html>

I expected this to display "Hello World!" but the result is "Hello!".
In hello.tag, this.opts.name is an empty string.

Did I miss something, or is there a real problem?

Version bump / dev branch

Could riot/route get a patch version bump and be updated in the next riot release?
There are a couple bug fixes that would be nice to include along with riot.
Also, the dev branch needs to be merged into master.

Isomorphic examples

I see that the docs mention riot-route is capable of isomorphic operation.

Is it possible to run two routers at once?

Routing without hash !

Hi guys (@cognitom @GianlucaGuarini ), is it possible to have routes without hash ?

I tried this :

riot.route.base('/')

It's working for /first but it can't get the second one in /first/second and I get this error :

capture d ecran 2016-02-10 a 00 47 04

I get the same error with just adding trailing slash like that /first/

It's the way used here https://github.com/riot/examples/blob/gh-pages/router-complex/index.html#L28 but it seems not working.

As I said on Gitter :

In fact the riot.route.base canโ€™t be the same as parser

#/first/second is working
/first#second is working
/first/second is not working

Obviously, this bug appears only when we enter the adress directly in the adress bar. I get almost the same bug with every version of superstatic.

Dev branch tests failing

I wanted to make a new riot-route release but it seems that the tests keep failing in the dev branch. @cognitom any clue about what's the issue? The master branch does not have any problem

Only route registered routes

Note: Using Riot 2.3.1
So I was rewriting my webapp which used:
http://example.com#media/id

In the new version the base by default is '#' but it affects every link in the webpage, using or not using '#' so I couldn't click any links because it didn't do anything at all. I really needed to get it working so I finally changed the base to '/' and then the url in the adressbar started to change as I clicked the links but, It does nothing, just works with registered routes, in my case '/media...' after changing the base.

To get it working I needed to register '/..' and then redirect by javascript if the destiny was different from the origin. Here is the code (Which right now doesn't think in queries) I used to get this working If it is of any help:

getUrl = ->
  "#{window.location.protocol}//#{window.location.host}#{window.location.pathname}"

oldMediaId = null
baseUrlForRouter = getUrl()

$(document).ready ->
  riot.route.base('/')

  riot.route 'media/*', (mediaid)->
    if mediaid? and oldMediaId != mediaid
      mediaPopupExec(mediaid)
      oldMediaId = mediaid

  riot.route '/..', () ->
    tUrl = getUrl()
    if tUrl != baseUrlForRouter
      window.location.replace(tUrl)

  riot.route.start(true)

So I can't find anything to solve it in a more official way. Usually in ExpressJS (Node.js) routes are like (req, res, next), and the next param is to call the next registered route which fits the actual route with his filter. If it doesn't have any other, it makes the default move, which in Express usually would be 404 because It doen't find any route, but here would be to send it to the clicked url.

In less words: When any route doesn't satisfy the asked route, it ""shouldn't do event.preventDefault()"" (Just as an example XD)

Sorry if there is an official way to do this, but I couldn't find it :S

Default base path

I've found this doesn't work out of the box without setting riot.route.base('/')
Since this now uses history.pushState shouldn't the default base be '/' instead of '#'?

Mapping routes to tags

Does anyone have a best practice or nice way to show/hide tags on a per-route basis? Ideally it would be mounting/unmounting the tag from the DOM entirely over simply showing/hiding, but I'm interested to see what others are doing.

Template literals break IE

Do you want to request a feature or report a bug?
This is a bug

What is the current behavior?
The page does not open in ie11. I get an error: Invalid character

What is the expected behavior?
No error

IE is breaking when it tries to evaluate the template literal here:
https://github.com/riot/route/blob/master/dist/cjs.route.js#L59

Per the MDN it doesn't look like those are supported in IE at all.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

Steps to reproduce:
Try to use the router in an application loaded into IE11

Open in new window/tab?

I'm used to link with a CTRL+click opening in a new tab/window. Is there a way to do that with the riot.route?
Or replace my riot.route with a href that the router picks up?

Thanks!

regression Bug of the router API?

riot/riot#1385

    /**
     * Disable the default riot route parser
     */
    riot.route.parser(function(path) {
    console.info("parser",path);
        return path; // return the path "as-is"
    });

    /**
     * Handle route change event
     */
    riot.route(function (path) {
        console.info("route is change to",path);
    });

    riot.route.start(true);

I expect that my callback is called on every change of the url (as in the version 2.3.4)

But it is not true in case the route is changed from index.html#blog to index.html#
The callback in the route.parser is invoked with empty path, and the riot.route callback is not called

PS: I don't know how to generate route problem with plunker

Routing bug after `riot.route('some/path')`

I discovered strange behavior that I believe can't be right. I'm seeing this on

  • windows 7
  • IE 11.0.9600.18449
  • riotjs 2.6.2
  • riot-route 2.5.0

Have a look at the plunkr here and click the links one after the other:
https://plnkr.co/edit/bGUkr1sueLDtcFrxd9sj

The problem is that the last click actually does change the url but no events are triggered (hashchange, popstate), also the riot handler is not run as in the steps before.

Also, I noticed that step 3 doesn't seem to add state. Perhaps this is why IE thinks that the current fragment is already "#a/b" so there is no event to trigger?

Any ideas?

click back button on browser doesn't go back to the last state?

Hi guys, with the riot-router, when I click the back button on the browser, the page address did change back to the previous one but the page was not reloaded. Is this a bug or designed like this? if expected, how should I make the content also change back? Regards!

Remove /

Hi,
i have a route.base('/translations)
and when i click on link with href="/translations/login" my url becoming /translationslogin.
How i can create translations/login?

riot-route-tag: tag based router for Riot.js

I'm thinking about tag-based router as a new feature. I'm now working on feature/route-tag branch and I'd like to share my current idea here. Nothing was decided yet. Any feedback is welcome!

Todos

  • for the first release
    • implement riot-route-tag (draft)
    • write tests
    • 2 packages in 1 repo 2 builds in 1 repo
    • adjust api specs (gathering ideas)
    • write documents
  • for the second release
    • fix some logic on riot-route
    • maybe a little fix on riot, too

Specs (proposal)

<app>
  <router>
    <route path="fruit/apple"><p>Apple</p></route>
    <route path="fruit/banana"><p>Banana</p></route>
    <route path="fruit/*"><inner-tag /></route>
  </router>
</app>

<inner-tag>
  <p>{ name } is not found</p>
  <script>
    this.on('route', name => this.name = name)
  </script>
</inner-tag>
  • <router>
    • it can contains multiple routes
    • it has base attribute (optional) maybe later
    • equivalent to const r = route.create() so it creates subrouter
  • <route>
    • it has path attribute
    • <route path="fruit/apple"> is equivalent to r('fruit/apple', () => { ... })
    • when the route has selected, it triggers route event on its children and passes some arguments to them

Two builds:

We could import them like this:

import route from 'riot-route'
// or
import route from 'riot-route/lib/tag' // note that it's not same as cjs below
const route = require('riot-route')
// or
const route = require('riot-route/tag')

Q&A

  • Q: What is packages dir?
    • A: to provide 2 packages in one repo
  • Q: Why not making a separated repo?
    • A: riot-route-tag is tightly coupled with riot-route
  • Q: Why two npm packages?
    • A: because of ES6 and CJS modules handling. We have no general way to provide submodules in both at this point: require('riot-route/tag') is not compatible with import 'riot-route/tag'.
  • Q: Why now?
    • A: Riot v3 has got much better if implementation ๐Ÿ˜„

Related informations:

Add Middleware to Routes

It would be interesting to have the option of middlewares on routes, executing before they get properly handled. E.g.

riot.route('/products/new', function() {
    // show view
}, ['UserController.isLogged']);

The idea is that middleware would always return a boolean. true firing the route callback, false preventing it from being handled.

There is also the .next() approach, discussed on Issue #25. Maybe we could define which approach would be the more interesting.

should decode URI

The router should call decodeURIComponent on parameters before providing them to the callbacks, so that the callbacks receive the intended values rather than the URI-encoded values.

Routing priority broken

Previously, when a match is found, no other routes are triggered. Now multiple routes are firing.

I noticed this updating from riot 2.3.18 -> 2.5.0.
It appears to be caused by changes in riot observable, because it works correctly if I roll that back. Nothing in this route repo has changed in a while.


Example:

route('/post/*.amp.html', function() { /* */ })
route('/post/*', function() { /* */ })

Given the url: /post/title-of-my-post
The expected result is for the second route to trigger.
The actual result is both get triggered, and also appears to be a race condition of which one gets triggered first.

Route match action should receive parsed segments

There's very little point in having a route matcher that does not (1) regard the values obtained by riot.parser.fn1 and (2) inconsistently produces callback function parameters.

Eg:

riot.route('/fruit/*', function(name) { /* */ })
riot.route('/fruit/apple', function() { /* */ })
riot.route('/fruit/orange', function() { /* */ })

Not only is there a name parameter JUST for wildcard matching, but this setup requires fruit as the bare minimum abstraction.

Expectedly, all route callbacks should plug into the values obtained by parser.fn1. In the default scenario, this looks like:

riot.route('/fruit/*', function(collection, id, action) { /* */ })
riot.route('/fruit/apple', function(collection, id, action){ /* */ })
riot.route('/fruit/orange', function(collection, id, action) { /* */ })

Of course, some parameters may still be undefined, but at least you can always expect a set of parameters in the callback.

My second point: We have to have a full set of routes just for fruit, and will have to repeat the same set for cars and another for trees, etc.

This practice only makes sense when you're designating routes for a specific tag or a specific set of tags. This same practice prevent you from having a succinct, global level routes declaration.

The same solution allows for:

// (1)
riot.route('..', function (collection, id, action) {
  // ..
});

// (2)
riot.route('fruit/apple/..', function (custom, parser, args) {
  // .. long-tail url, read it
});

(1): While this isn't a recommended only solution, it allows for a nice last resort/"catch-all" which has the power to run its own logic based on params

(2): Dependent on our desired URL structure (and appropriate parser fn), we can allow for deep, complex URLs and handle them all at once without having to declare multiple blocks, repeating boilerplate.

Anyway, Issue getting a bit long here. If this is approved, I have the matching PR ready to be opened. It's a simple 2-line fix

Coveralls doesn't work

After repo name changed (riot-router --> riot-route), coveralls seems not working. I've already changed the source and synced it. There's something buggy. Some issues like this is reported on coveralls' repo.
lemurheavy/coveralls-public#603

Is there a CDN release of this

I'm playing around with the 3.0 version of Riot and the router has been removed. I'm wondering if there is a release of the stand alone router on a CDN someplace?

I've checked a few including cdn.jsdelivr.net (where I'm grabbing the 3.0 riot from) but I cant seem to locate the router code.

I'm using https://cdn.rawgit.com/riot/route/master/dist/route.js for now, but a released version on CDN would be much better.

subRoute.stop() doesn't work (stop is undefined)

I need to load and unload sub-components dynamically and they have inner routes themselves.
I wanted to stop subRoute when component is unmounting, so the handlers wouldn't accumulate.

The code from router API doesn't work. I've tried in in playground and the error is same.

var subRoute = riot.route.create()
subRoute('/fruit/apple', function() { /* */ })
subRoute.stop()

Unable to include lib/index.js in the new riot 2.3.0 build

I have tried including the new router in the new riot build https://github.com/riot/riot/blob/2.3.0/lib/riot.js but it does not pass the old router tests. Do I need to test a build script with esperanto or do we stick with smash? In case we want to use smash the router code should be wrapped in its own IIFE avoiding to pollute the global scope. What do you recommend?

Roadmap

Now it's time to think about the next :-)

  • server-side support #18
  • replaceState #47
  • prepare to make it optional for Riot.js 2.4
  • rewrite into ES6

Other candidates:

  • next()? #25
  • route deconstructor #36
  • decode URI #29

Note: #36 would be nice, but I'd like to keep it small, too. #29 breaks specs.

Is change routing in routing callback supported?

Hi, my scenario is like this:

  • When there is no path in the url, I want to change the url to some default path

My code is now like this (v2.3):

studyRoute(view, id) {
    switch(view) {
    case 'news':
      require('./views/news-view.html')
      self.loadView('news-view', id)
      break
    default:
      riot.route('news/1')     // is this supported?
    }
  }
  riot.route(self.studyRoute)
  riot.route.start()
  riot.route.exec()

If I start with empty path url, it will bring me to /#news/1, which is correct. However after changing the url, the studyRoute is not called again, thus my actual logic is not executed.

I am not sure if it is due to I am not writing the correct code, or a bug. Please advise :)

Riot routing and links within a page

If the route base is # how do I link to a specific spot within a page? Normally you'd do something like some-page/#target but that would trigger the Router. Any help here would be appreciated! :)

Unexpected behaviour of route.start(true)

I have faced with strange behaviour of single page application built with riot.js . Its rendering was delayed until loading of all external js libraries finishes. It includes async externals, iframes content, etc. After investigation it became clear that route.start(true) calls appropriate route handler only after 'load' event browser trgiggers.

It was not trivial to find the reason, a lot of time was spent. I suggest to describe this behaviour in documentation and suggest to explicitly call of route.exec() where it`s possible. My problem was solved as follows:

riot.route.start() // call of start(true) delays route processing before 'onload' event raises
riot.route.exec() // so need call exec() in place

riot.route not working in ie for 2.3.1

I have this setup for riot routing -

var router = function(page,id) {
function change_page(current_page){
RiotControl.trigger('page_changed', current_page, xmenu.last_page)
xmenu.last_page = current_page;
}
page = !page ? 'home' : page;
change_page(page);
}
// Riot router
riot.route(router)
// Execute router function once for rendering the items
riot.route.exec(router);

when I click a link with href="#home" or set location.hash the callback function 'router' is never called in ie11 works fine in chrome and ff.

Add standalone route release

Currently the dist folder contains route.js that is meant to be used in nodejs but actually there is no way to use a standalone release that could be directly included in a browser environment without riot or an additional build step. Probably the package.json should point to the lib/index.js file and the dist/route.js should contain a build release including riot-observable as well.

Introduces WebdriverIO

For testing this library, I'd like to introduce WebdriverIO. We're using Karma now, but even if it's a simple unit test, it can't handle page transition. It makes the tests difficult, especially for the libraries like riot-route.

I've done the most part of the research. But some points are still open. Your feedback is welcome.

  • WebdriveIO research (ver4 is awsome, actually)
  • makes Java free environment locally
  • creates phantomjs lanucher for WebdriveIO
  • how to measure the coverage
  • how to live together with Karma tests

Saucelabs widget doesn't support multiple test in one repo, IFIK...

Partial server-side support

We should simply allow something like the exec method to work server-side. This way, you can pass it the request path and let your route handlers do any rendering they normally would do on the client side.

I can work on a PR if you agree with the idea.

route & route.base functions allow regex

I'm starting to create an app for one client using Riot and one of the use cases is that the base route can change due localization, so I tried to use a regular expression in riot.route.base method and it worked as a charm even though the docs don't mention it.

I've been inspecting the code to see if that's expected or not, because I wanted to make sure that it won't stop to work in path/minor version and I've clearly seen that method comments (api docs) specify that the parameters can be a string or RegExp, so I make the assumption that's a feature.

If you can assert all of this, I will send a PR with an update of the docs.

Makes route.exec() callable without callback

@tipiirai can't we change the API of route.exec()?

v2.2 allowed a custom callback for this function, but I'd like to make it callable without a callback.

// v2.2
riot.exec(callback)

// v2.3
riot.exec()

I often use it this manner in v2.2, but it looks redundant:

// v2.2
var callback = function(id) {
  /* do something */
}
riot(callback)
riot.exec(callback)

And if there're multiple routings, we have no way to exec. Any advice or thought?
(At this time, this would be the only point which is not compatible with v2.2)

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.