Code Monkey home page Code Monkey logo

svelte-router's Introduction

Svelte Router

Simple Svelte Router for Single Page Applications (SPA), inspired by Vue Router. Features include:

  • Nested route/view mapping.
  • Modular, component-based router configuration.
  • Route params, query, wildcards (powered by path-to-regexp).
  • Navigation guards for navigation control.
  • Links with automatic active CSS classes.
  • HTML5 history mode or hash mode (powered by history).

To see the details code documentation, please read the Code Documentation.

Notice

This project is not being actively maintained by the author of package. Any community contribution would be more than welcomed keep this project alive.

Quick Links

Table of Content

Installation via NPM or Yarn

npm install -D @spaceavocado/svelte-router
yarn add @spaceavocado/svelte-router -D

Webpack Setup

Please see the Svelte Webpack Template. Important setup in the webpack.config.js:

resolve: {
  // This alias is important to prevent svelte mismatch
  // between your code, and the 3rd party components.
  alias: {
    svelte: path.resolve('node_modules', 'svelte')
  },
  extensions: ['.mjs', '.js', '.svelte'],
  mainFields: ['svelte', 'browser', 'module', 'main']
},

module: {
  rules: [
    {
      test: /\.svelte$/,
      // Do not exclude: /(node_modules)/ since the router 
      // components are located in the node_modules
      use: {
        loader: 'svelte-loader',
        options: {
          emitCss: true,
          hotReload: true
        }
      }
    }
  ]
}

Webpack Boilerplate Project Template

For a quick start, you can use svelte-router-template - Webpack boilerplate template project for spaceavocado/svelte-router.

Live Preview.

Rollup Setup

rollup.config.js:

import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import svelte from 'rollup-plugin-svelte';

export default {
  input: './src/index.js',
  output: {
    file: './dist/bundle.js',
    format: 'iife'
  },
  plugins: [
    resolve(),
    commonjs({
      include: 'node_modules/**',
    }),
    svelte(),
    babel({
      exclude: 'node_modules/**',
    }),
  ]
}

Essentials

Note: All code below uses ES2015+.

Setup the Router

All we need to do is map our components to the routes and add root RouterView component, here's a basic example of app component uses as the main Svelte component.

index.js:

// The base component
import App from './app.svelte';

// Turn on the engine
new App({
  target: document.body,
});

app.svelve:

<script>
import createRouter from '@spaceavocado/svelte-router';
import RouterView from '@spaceavocado/svelte-router/component/view';

// View components
import ViewHome from './views/home.svelte';
import View404 from './views/404.svelte';

createRouter({
  routes: [
    { 
      path: '/',
      name: 'HOME',
      component: ViewHome,
    },
    {
      path: '*',
      component: View404,
    },
  ],
});
</script>

<RouterView />

This is an example of the minimalist plug & play setup of the Svelte Router. For more details:

Route Configuration

A route can be configure with these properties:

Property Description Type
path A string that equals the path of the current route, always resolved as an absolute path. e.g. "/foo/bar". Please see Dynamic Route Configuration for advanced usage. string
redirect Redirection to different route, or to external site. Please see Route Redirection for advanced usage. boolean, object, function
name The name of the current route, optional. string
component Svelte component. It could be be omitted if the route has nested routes. function
meta Route meta object, meta is used a bucket for your custom data on route object. object
props Declaration of component properties passed to the component by the route. Please see Passing Props to Route Components for more details. boolean, object, function
children Collection of children/nested routes. Please see Nested Routes for more details. object[]
createRouter({
  routes: [
    { 
      path: '/',
      name: 'HOME',
      component: ViewHome,
      meta: {
        static: 5,
        dynamic: () => {return 5;},
      }
    },
    { 
      path: '/services',
      name: 'SERVICES',
      children: [
        { 
          path: '/',
          name: 'SERVICES_HOME',
          component: ViewServices,
        },
        { 
          path: '/design',
          name: 'SERVICES_DESIGN',
          component: ViewServicesDesign,
          props: {
            title: 'Services / Design',
          }
        }
      ]
    },
    { 
      path: '/users/:id(\\d+)',
      name: 'USER_PROFILE',
      component: ViewUserProfile,
      props: (route) => {
        return {
          userId: route.params.id,
        };
      },
    }
  ],
});

Dynamic Route Configuration

  • The route path could contain dynamic parameters, e.g. path: '/users/:id'. Please see path-to-regexp for more information how to configure the name, optional, etc,. parameters.
  • Special case is path: '*' which means any URL, this route should be the last route in your routes definition.
  • All resolved dynamic parameters are accessible on the resolved route object.

Route Redirection

To redirect a route, you can configure it like so:

// Redirect from /a to /b
{ 
  path: '/a',
  redirect: '/b',
}

// External site redirect
// Must start with 'http' or 'https'
{ 
  path: '/a',
  redirect: 'https://github.com/spaceavocado/svelte-router',
}

// Redirect to named route
{ 
  path: '/a',
  redirect: {
    name: 'ROUTE_NAME',
  },
}

// Dynamic redirecting
// "to" is Route Object
// Return value must be URL or a Route.
{ 
  path: '/a',
  redirect: (to) => {
    return {
      name: 'ROUTE_NAME',
    }
  },
}

Please see Route Object for more details.

Passing Props to Route Components

By default, props are not automatically passed to the route component, this could be change to:

Automatically Pass Route Params as Component Props

All route dynamic props are auto-passed to the component.

// app.svelte
{ 
  path: '/users/:id(\\d+)',
  name: 'USER_PROFILE',
  component: ViewUserProfile,
  props: true,
}

// ViewUserProfile.svelte
export let id;

Pass Custom Object as Component Props

// app.svelte
{ 
  path: '/',
  name: 'HOME',
  component: ViewHome,
  props: {
    title: 'Hello World',
  },
}

// ViewHome.svelte
export let title;

Use a Function to Resolve the Component Props

Please see Route Object for more details.

// app.svelte
{ 
  path: '/users/:id(\\d+)',
  name: 'USER_PROFILE',
  component: ViewUserProfile,
  props: (route) => {
    return {
      title: 'User Profile',
      id: route.params.id,
    }
  },
}

// ViewUserProfile.svelte
export let title;
export let id;

Auto Passed Route Prop

Route property of type Route Object is auto-passed to the route component.

component.svelte:

<script>
export let route;
</script>

Nested Routes

  • Please see Route Configuration for the base information about the routes configuration.
  • Nested route has access to its own parameters and all parent's route parameters:
    { 
      path: '/users/:id(\\d+)',
      children: [
        {
          path: '/',
          name: 'USER_DETAIL',
          component: ViewUserDetail,
        },
        {
          path: '/message/:msgId(\\d+)',
          name: 'USER_MESSAGE',
          component: ViewUserMessageDetail,
        }
      ],
    },
    {
      path: '/services',
      component: ViewServices,
      children: [
        path: '/design',
        component: ViewServicesDesign,
      ]
    }
    
    // Resolved USER_MESSAGE route will have access to 
    // id, and msgId params.
  • The component could be omitted if the route has nested routes (please see the example above), it this case ViewRouter component will be used to pass through the components, please see Router View for more details.
  • If the route has nested routes, and it has defined component, than the component must internally use Router View component to pass though the routed view components on it's own nested routes.
  • All routes should start with trailing slash.

Router Link Component

<script>
import RouterLink from '@spaceavocado/svelte-router/component/link';

<!-- URL -->
<RouterLink to='/services/design'>Navigate by URL</RouterLink>

<!-- Location Object -->
<RouterLink to={{name: 'USER_DETAIL', params:{id: 5}}>Navigate by Location</RouterLink>

The route link is the base component for routing action. The route link renders a < a > DOM element with click action triggering route change. The active class is auto-resolved. Component parameters:

Property Description Type
to navigation URL or navigation Location, please see Location Object for more details. string, Location
replace Replace rather the than push into the history, defaults to false. boolean
exact The default active class matching behavior is inclusive match, i.e. it matches if the URL starts with link url. In the exact mode, the url must be be the same (excluding query param and hash param). Defaults to false. boolean
cls Link base class name, defaults to ''. string
activeClass Link active class name, if not defined, it defaults to the active class defined on the router. string
disabled Disable navigation action, and set "disabled" css class. Defaults to false. boolean

Router Link Events

<script>
import RouterLink from '@spaceavocado/svelte-router/component/link';

// Navigation has been completed
function handleOnCompleted() {}

// Navigation has been aborted
function handleOnAborted() {}
</script>

<RouterLink to='/services/design' on:completed={handleOnCompleted} on:aborted={handleOnAborted}>Navigate by URL</RouterLink>

Router View Component

<script>
import RouterView from '@spaceavocado/svelte-router/component/view';
</script>

<RouterView />
  • The route view acts as SLOT for resolved route component, i.e. it will be replaced run-time with the component defined on the given route.
  • For nested routes, if the parent route (the one having nested routes) has defined it's own component, the component must use internally ViewRouter component to pass through the nested route components. If the component is not defined on the parent route, it auto pass through.

Advanced

Programmatic Navigation

Besides the Router Link Component, the route could be changed like so:

import {router} from '@spaceavocado/svelte-router';

// URL
$router.push('/services/design');

// Location Object
$router.push({
  name: 'USER_DETAIL',
  params: {
    id: 5,
  },
  query: {
    code: 'system_code',
  },
  hash: 'sidebar',
});

Note: the router can be accessed after the createRouter function is executed, and it must be accessed as $router since it is Svelte read-able store object.

More information:

Navigation Guard

The navigation guards are primarily used to guard navigations either by redirecting it or canceling it.

Create a Navigation Guard

import {router} from '@spaceavocado/svelte-router';

// The guard callback is called when a navigation occurs,
// the next function must be called to continue the navigation.
$router.navigationGuard((from, to, next) => {
  next();
});

Note: the router can be accessed after the createRouter function is executed, and it must be accessed as $router since it is Svelte read-able store object.

"from, to" are Route Object.

Navigation Guard Next Action

Continue
next();

Move on to the next hook in the pipeline. If no hooks are left, the navigation is confirmed.

Abort
next(false);

Abort the current navigation.

Redirect
// URL
next('/services/design');

// Location Object
next({
  name: 'USER_DETAIL',
  params: {
    id: 5,
  },
  query: {
    code: 'system_code',
  },
  hash: 'sidebar',
});

Abort the current navigation and redirect to new navigation.

More information:

Error
next(new Error('internal error'));

Abort the current navigation, and trigger onError event on the router.

More information:

Lazy Loaded Component

View components could be loaded asynchronously, i.e. lazy loading, e.g:

app.svelve

<script>
import createRouter from '@spaceavocado/svelte-router';
import RouterView from '@spaceavocado/svelte-router/component/view';

// View components
import ViewHome from './views/home.svelte';
import View404 from './views/404.svelte';

// Webpack dynamic import
const asyncView = (view) => {
  return new Promise((resolve) => {
    const component = import(/* webpackChunkName: "view-[request]" */ `./view/${view}.svelte`);
    resolve(component);
  });
};

createRouter({
  routes: [
    { 
      path: '/',
      name: 'HOME',
      component: ViewHome,
    },
    {
      path: 'some-page',
      component: asyncView('some-page'),
    }
    {
      path: '*',
      component: View404,
    },
  ],
});
</script>

<RouterView />

Note: To load async component, the load function must return a Promise, and resolve must return a module object:

{
  // The default (default module export function) must the Svelte Component function
  // Please see the webpack example above.
  default: function(){}
}.

API

To see the details code documentation, please read the Code Documentation

Create Router

import createRouter from '@spaceavocado/svelte-router';

// Please see the opts below.
const routerOpts = {};

// Router is Svelte read-able store, therefore it must be
// accessed with $ prefix, e.g. $router.
// To access the router instance in other files, please see "Access Router Instance".
const router = createRouter(routerOpts);

Throws when the route options are invalid.

Router Options

Property Description Type
mode History mode. Supported values: 'HISTORY', 'HASH'. string
basename The base URL of the app, defaults to ''. string
hashType Hash type. Relevant only for HISTORY_MODE.HASH. Supported values: 'PUSH', 'REPLACE'. string
routes router routes. object[]
activeClass CSS class applied on the active route link. Defaults to "active". string

Note: History modes could be accessed like so:

import {ROUTER_MODE} from '@spaceavocado/svelte-router';

Note: Hash types could be accessed like so:

import {HASH_TYPE} from '@spaceavocado/svelte-router';

More information:

Access Router Instance

import {router} from '@spaceavocado/svelte-router';

Note: It must be accessed as $router since it is the Svelte read-able store object, to resolved auto subscribe/unsubscribe.

Router Methods

All route methods are accessible on the router, please see Access Router Instance.

start

$router.start();

This method is auto-called by the root Router View Component; it handles the on page load route resolution.

push

Push to navigation.

$router.push(rawLocation, onComplete, onAbort);

Throws when the rawLocation is invalid or when the path is invalid.

Parameters:

Name Description Type
rawLocation raw path or location object. string, Location
onComplete On complete callback function. Optional. function
onAbort On abort callback function. Optional. function

replace

Replace in navigation.

$router.replace(rawLocation, onComplete, onAbort);

Throws when the rawLocation is invalid or when the path is invalid.

Parameters:

Name Description Type
rawLocation raw path or location object. string, Location
onComplete On complete callback function. Optional. function
onAbort On abort callback function. Optional. function

back

Go one step back in the navigation history.

$router.back();

forward

Go one step forward in the navigation history.

$router.forward();

go

Go to a specific history position in the navigation history.

$router.go(n);

Parameters:

Name Description Type
n number of steps to forward or backwards (negative number). number

routeURL

Generate route URL from the the raw location.

const url = $router.routeURL(rawLocation);

Parameters:

Name Description Type
rawLocation raw location object. Location

navigationGuard

Register a navigation guard which will be called whenever a navigation is triggered. All registered navigation guards are resolved in sequence. Navigation guard must call the next() function to continue the execution of navigation change. Please see Navigation Guard

const unregister = $router.navigationGuard(guard);

// To unregister the navigation guard:
unregister();
unregister = null;

Parameters:

Name Description Type
guard guard callback function with (from, to, next) signature. Please see Navigation Guard Next Action function

"from, to" are Route Object.

onBeforeNavigation

Register a callback which will be called before execution of navigation guards.

const unregister = $router.onBeforeNavigation(callback);

// To unregister the event:
unregister();
unregister = null;

Parameters:

Name Description Type
callback callback function with fn(from, to) signature. function

"from, to" are Route Object.

onNavigationChanged

Register a callback which will be called when all navigation guards are resolved, and the final navigation change is resolved.

const unregister = $router.onNavigationChanged(callback);

// To unregister the event:
unregister();
unregister = null;

Parameters:

Name Description Type
callback callback function with fn(from, to) signature. function

"from, to" are Route Object.

onError

Register a callback which will be called when an error is caught during a route navigation.

const unregister = $router.onError(callback);

// To unregister the event:
unregister();
unregister = null;

Parameters:

Name Description Type
callback callback function with fn(error) signature. function

Location Object

Property Description Type
name Name of the route. string
params Route params dictionary object, if the route has defined dynamic route parameters, this object is required, with valid params to resolve the route URL. object
query Route query dictionary object. Optional. object
hash Route hash parameter. Optional. string
// Location object example
{
  name: 'USER_DETAIL',
  params: {
    id: 5,
  },
  query: {
    code: 'system_code',
  },
  hash: 'sidebar',
}

// Considering that USER_DETAIL is /user/:id(\\d+)
// the resolved URL will be:
// /user/5?code=system_code#sidebar

Route Object

Property Description Type
name name of the route. string
path location path use to resolve the route. string
hash url hash. string
fullPath the full resolved URL including query and hash. string
params route resolved params. object
query query parameters. object
meta route meta. object
action route action. string
matched resolved route records, please see Route Record Object In the case of nested route, it contains all matched routes, starting from root to the deepest route node. object[]

Route Record Object

Property Description Type
path location path use to resolve the route. string
name name of the route. string
component svelte component. string
meta route meta. string
params route resolved params. string
props props passed to component, please see Passing Props to Route Components. boolean, object, function

Changes

To see the changes that were made in a given release, please lookup the tag on the releases page. The full changelog could be seen here changelog.md

About

This project was inspired by Vue Router, designed mainly to explore and test Svelte in SPA realm. Any feedback, contribution to this project is welcomed.

The project is in a beta phase, therefore there might be major changes in near future, the annotation should stay the same, though.

Contributing

When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change.

Pull Request Process

  1. Fork it
  2. Create your feature branch (git checkout -b ft/new-feature-name)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin ft/new-feature-name)
  5. Create new Pull Request

Please make an issue first if the change is likely to increase.

License

Svelte Router is released under the MIT license. See LICENSE.txt.

svelte-router's People

Contributors

davidhorak 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

Watchers

 avatar  avatar  avatar  avatar

svelte-router's Issues

RouterLink does not output attributes passed

With the following code:

<RouterLink to="{{name: 'ABOUT'}}" class="navItem">About</RouterLink>

The class navItem is not passed to the generated a tag. In the console there's a message from link.svelte:86 that state: <Link> was created with unknown prop 'class'</Link>.

So it seems that handling for passing through attributes is missing(?).

Support for Analytics like Matomo

I want to integrate Matomo in my Svelte SPA?

I found this code in the Matomo Developer Guide:

window.addEventListener('hashchange', function() {
        _paq.push(['setCustomUrl', '/' + window.location.hash.substr(1)]);
        _paq.push(['setDocumentTitle', 'My New Title']);
        _paq.push(['trackPageView']);
});

How can use this code with your router? Could you help me?

Prevent Navigation on select child elements

Tell me what you think of this. In link.svelte, change line 73 to

on:click|preventDefault="{(e) => !e.target.closest('.preventNavigation') && navigate(to)}"

That gives us the ability to mark certain elements to not trigger nav. I don't know if this affects performance at all.

In my case, I have a list of link cards. Most of the card should navigate on click, but there are interactive elements on the cards.

Svelte:Head doesn't update, when switch between pages

In my Page Components, i use the <svelte:head> like this:

<svelte:head>
    <title>Website Title</title>
    <meta name="description" content="Website Description">
</svelte:head>

But when i switch between my pages, the svelte:head doesn't update... I always see the title and meta content from my Home Component.

When i use the svelte router package svero i don't have these issue...
How can i solve this?

Home absolute path

When navigating by name to HOME link should be relative not absolute

{
        path: "/",
        name: "HOME",
        component: Todos
      },
...
<RouterLink to={{ name: 'HOME' }}>Home</RouterLink>

When using web application server to serve svelte app there is problem(http://localhost:8080/svelte/):

  • no rote can be found so Todos is not showen
  • when navigation by RouterLink Home then url is http://localhost:8080/

``

RouterLink invalid route parameters

I define route:

{
        path: "/photos/:id(\\d+)",
        name: "Photos",
        component: Photos
}

In Photos I define:

export let id;

In RouterLink I define:

let photoId = 5;

<RouterLink to={{ name: 'Photos', parms: { id: photoId } }}>
          Photos
</RouterLink>

And routing to component Photos not working in console is error:

svelte-router/link, invalid route parameters, :TypeError: Expected "id" to be a string

Callbacks: "to, from" versus "from, to"

In some places in the docs, e.g. onNavigationChanged you say that the callback params are (to, from), and then in other places, e.g. /component/view.svelte:58, you say it's (from, to). Which one is it? When I run onNavigationChanged, it looks like (from, to) to me.

TypeError: de is undefined when selecting a link produced by <RouterLink>

If I write the link by hand in the address bar, the router works, switching to the desired view, but
when selecting the link produced by:

<RouterLink to={{name: 'Widgets'}}>Widgets</RouterLink>

(which is equal to the one entered by hand) the URL changes, but the page doesn't and the console displays the error:

TypeError: de is undefined

in module.js:1:4303, which is minified (it has inside this extract ... if(ue.has(e))return;ue.add(e),de.c.push(()=>{ue.delete(e),s&&(n&& ...)

my package.json:

{
  "name": "svelte-app",
  "version": "1.0.0",
  "devDependencies": {
    "@fortawesome/fontawesome-free": "^5.10.2",
    "@spaceavocado/svelte-router": "^1.0.13",
    "bulma": "^0.7.5",
    "npm-run-all": "^4.1.5",
    "rollup": "^1.12.0",
    "rollup-plugin-babel": "^4.3.3",
    "rollup-plugin-commonjs": "^10.0.0",
    "rollup-plugin-livereload": "^1.0.0",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-plugin-postcss": "^2.0.3",
    "rollup-plugin-svelte": "^5.0.3",
    "rollup-plugin-terser": "^4.0.4",
    "svelma": "0.0.11",
    "svelte": "^3.0.0"
  },
  "dependencies": {
    "@babel/core": "^7.5.5",
    "sirv-cli": "^0.4.4"
  },
  "scripts": {
    "build": "rollup -c",
    "autobuild": "rollup -c -w",
    "dev": "run-p start:dev autobuild",
    "start": "sirv public --single",
    "start:dev": "sirv public --single --dev"
  }
}

Store Router not updating

Hi there.. the router store is not updating or reacting..

My guess that is not creating an object or array brand new.. causing Svelte not realizing that the object/store has changed.
Screenshot from 2020-05-14 13-22-37

Anyway.. many thanks!
=)

Event Listener for URL Changes?

Hi,
thank you very much for this repo. It works very good, but my router doesn't work, when i manual change the URL in the URL Bar. I get a 404 Not Found Error...

My App.svelte looks like this:

import createRouter from '@spaceavocado/svelte-router';
import {ROUTER_MODE} from '@spaceavocado/svelte-router';
import RouterView from '@spaceavocado/svelte-router/component/view';

import Home from './pages/Home.svelte'
import Technic from './pages/Technic.svelte'

createRouter({
    routes: [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/solutions/technic',
        name: 'Technic',
        component: Technic
      },     
    ],
    mode: 'HISTORY',
    hashType: 'PUSH',
  })

How can i solve the problem?

Query parameters are not encoded

<RouterLink to={{ name: 'test', query: { a: 'x&b=2' } }}>Click</RouterLink>

This will create a bad URL like /test?a=x&b=2 (which will actually set { a: 'x', b: '2' }) instead of the expected URL /test?a=x%26b%3D2.

On the other hand, the query in route.query also isn't decoded. Both would need to be done to fix this issue.

Optional parameters in the URL cause crash in isWholeNumber

Try a route such as /foo/:bar? and navigate to /foo. It will crash in isWholeNumber trying to check whether the param bar is a number (which is undefined).

bundle.js:35421 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'match')
    at isWholeNumber (bundle.js:35421:13)
    at resolveNumber (bundle.js:35611:10)
    at setParamValue (bundle.js:35625:26)
    at createRouteRecord (bundle.js:35640:6)
    at Router.matchRoute (bundle.js:36232:25)
    at Router.resolveRoute (bundle.js:36181:19)
    at Router.push (bundle.js:35904:13)
    at Router.onHistoryChange (bundle.js:36090:15)
    at Router.start (bundle.js:35787:13)
    at bundle.js:36989:13

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.