Git Product home page Git Product logo

serverless-http's Introduction

serverless-http

Description

This module allows you to 'wrap' your API for serverless use. No HTTP server, no ports or sockets. Just your code in the same execution pipeline you are already familiar with.

Sponsors

Thank you to Upstash for reaching out to sponsor this project!

Upstash

Upstash: Serverless Database for Redis

  • Serverless Redis with global replication and durable storage
  • Price scales to zero with per request pricing
  • Built-in REST API designed for serverless and edge functions

Start for free in 30 seconds!

Support

Supported Frameworks

(* Experimental)

  • Node (http.createServer)
  • Connect
  • Express
  • Koa
  • Restana
  • Sails *
  • Hapi *
  • Fastify *
  • Restify *
  • Polka *
  • Loopback *

Supported Providers

  • AWS
  • Azure (Experimental, untested, probably outdated)

Examples

Please check the examples folder!

Usage example using the Koa framework

const serverless = require('serverless-http');
const Koa = require('koa'); // or any supported framework

const app = new Koa();

app.use(/* register your middleware as normal */);

// this is it!
module.exports.handler = serverless(app);

// or as a promise
const handler = serverless(app);
module.exports.handler = async (event, context) => {
  // you can do other things here
  const result = await handler(event, context);
  // and here
  return result;
};

Usage example using the Express framework with Azure

const serverless = require('serverless-http');
const express = require('express');

const app = express();

app.use(/* register your middleware as normal */);

const handler = serverless(app, { provider: 'azure' });
module.exports.funcName = async (context, req) => {
  context.res = await handler(context, req);
}

Other examples

json-server-less-ฮป - using serverless-http with json-server and serverless framework in AWS

Limitations

Your code is running in a serverless environment. You cannot rely on your server being 'up' in the sense that you can/should not use in-memory sessions, web sockets, etc. You are also subject to provider specific restrictions on request/response size, duration, etc.

Think of this as a familiar way of expressing your app logic, not trying to make serverless do something it cannot.

Contributing

Pull requests are welcome! Especially test scenarios for different situations and configurations.

Further Reading

Here are some more detailed examples and advanced configuration options as well as provider-specific documentation

serverless-http's People

Contributors

adrai avatar akinoniku avatar awwong1 avatar bsdkurt avatar daniel-ac-martin avatar dependabot[bot] avatar dominiklessel avatar dougmoscrop avatar ersims avatar fastner avatar jheising avatar joe-niland avatar john-tipper avatar ktonon avatar liamchilds avatar miguel-mad avatar mpvosseller avatar mvayngrib avatar mythofleader avatar ncipollina avatar nicksrandall avatar palfrey avatar richwandell avatar rochdev avatar rschick avatar sachinshekhar avatar starkwang avatar steve-human avatar tomc974 avatar tomhallam 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

serverless-http's Issues

[Request] Add support for multi-value parameters

Just want to raise this so it is here for future reference, this is the same as CodeGenieApp/serverless-express#196. Application load balancer supports this via a configuration option in the backend, and api gateway has recently got support for it. Pretty nasty but unfortunately pretty common in a lot of codebases these days.

For application load balancer this is an example event:

multiValueHeaders:  {
   accept: [ 'application/json, text/javascript, */*; q=0.01' ],
  'accept-encoding': [ 'gzip, deflate, br' ],
  'accept-language': [ 'en-GB,en-US;q=0.9,en;q=0.8' ],
  ...
}
multiValueQueryStringParameters: {
  'dateRange%5B%5D': [ '2018-12-14', '2018-12-14' ],
  roleId: [ '0' ]
}

The behaviour of my express app currently with that same request is:

req.query == {
  'dateRange': ['2018-12-14', '2018-12-14' ],
  'roleId': '0'
}

Not entirely sure how you would go about handling this in a useful manner.

I would probably be happy if there was some way of way of pre-processing the event so I have a hook to transform the data to ensure that ServerlessRequest behaves itself.

The wrong request ID is being added to the headers

Right now the request ID being used is context.awsRequestId, but that is the request ID of the Lambda invocation, not the API Gateway request. The correct request ID is event.requestContext.requestId.

Always call default route

why always call "/" route after upgrade to 1.5.4 ?
my code is :

const express = require('express');
const serverless = require('serverless-http');
const app = express()

//first route
//always call this
app.get('/', function (req, res) {
	res.send('Hello World!')
})

//the second route
//never call this
app.get('/test', function (req, res) {
	  res.send('Hello Test!')
})

module.exports.handler =  serverless(app);

Accessing context fields from API Gateway

First, thanks for this library! I need to access some attributes from the API Gateway: the context.requestId and context. requestTime. I was able to fetch the get the requestId by using:

module.exports.handler` = serverless(app, {
  request: (req, event, context) => {
    req.context = event.requestContext;
    req.awsRequestId = context.awsRequestId;
    req.eventAws = event;
    req.contextAws = context;
  }
});

However, I am not seeing the dates. I show al the context, and I got the following:

{
    "resource": "/boosts",
    "path": "/boosts",
    "httpMethod": "POST",
    "headers": {},
    "queryStringParameters": null,
    "pathParameters": null,
    "stageVariables": null,
    "requestContext": {
        "path": "/boosts",
        "accountId": "xxx",
        "resourceId": "xxx",
        "stage": "test-invoke-stage",
        "requestId": "test-invoke-request",
        "identity": {
            "cognitoIdentityPoolId": null,
            "cognitoIdentityId": null,
            "apiKey": "test-invoke-api-key",
            "cognitoAuthenticationType": null,
            "userArn": "arn:aws:iam::xxx:user/Marcelo_Olivas",
            "apiKeyId": "test-invoke-api-key-id",
            "userAgent": "userAgent",
            "accountId": "xxx",
            "caller": "xxx",
            "sourceIp": "sourceIp",
            "accessKey": "xxx",
            "cognitoAuthenticationProvider": null,
            "user": "xxx"
        },
        "resourcePath": "/boosts",
        "httpMethod": "POST",
        "extendedRequestId": "test-invoke-extendedRequestId",
        "apiId": "xxx"
    },
    "body": "{\n\t\"attribute\": \"another.attribute\", \n\t\"boost\" : 1, \n\t\"status\" : \"analysis\"\n}",
    "isBase64Encoded": false
}

Now for the events, I was able to get:

{
    "callbackWaitsForEmptyEventLoop": false,
    "logGroupName": "/aws/lambda/three-eyed-raven-dev-createBoost",
    "logStreamName": "2018/05/11/[$LATEST]9be2c7eadced41b487b87d1a1885d761",
    "functionName": "three-eyed-raven-dev-createBoost",
    "memoryLimitInMB": "1024",
    "functionVersion": "$LATEST",
    "invokeid": "xxx-yyy-11e8-aaa6-aaa",
    "awsRequestId": "xxx-yyy-zzz",
    "invokedFunctionArn": "arn:aws:lambda:us-east-1:aabbvv:function:three-eyed-raven-dev-createBoost"
}

Thanks for the help, and again...thanks for the library!

How to run serverless inside function

This may be something super simple, but I can't figure it out.

Instead of pointing my handler to a wrapped function can I run a function before it?

I need to make an ssm call to get a variable for what I'm passing into express.

export default endpoint = () => serverless(app)

Request fails when using aws api gateway and a cognito authorizer

Seems to me that aws maps cognito's claims to request's body and turns it into a object.
Therefore, this line is executed.

Error:

{
	"errorMessage": "Unexpected event.body type: object",
	"errorType": "Error",
	"stackTrace": [
		"getBody (/var/task/node_modules/serverless-http/lib/request.js:17:9)",
		"new ServerlessRequest (/var/task/node_modules/serverless-http/lib/request.js:29:18)",
		"Promise.resolve.then (/var/task/node_modules/serverless-http/serverless-http.js:30:25)"
	]
}

Include baseUrl in request object

The endpoint for lambdas will have the stage as their baseUrl. However, currently, requests sent to the wrapped express app don't include this. This means that redirects will not work as expected.

e.g. a request to an express.static directory path without the trailing "/" attempts to redirect to the same path appended with "/". But when wrapped in serverless-http the redirect is wrong.

https://{host}/{stage}/staticdir => https://{host}/staticdir/

Body is undefined while running local

Can't be run locally, perhaps event is empty

serverless  invoke local --function handler --log
Type Error ---------------------------------------------

     Cannot read property 'body' of undefined

AWS Lambda time out when using `connect-dynamodb`

When attempting to use connect-dynamodb, a DynamoDB-backed session middleware for express, the AWS Lambda function times out according to the logs.

I traced it down and it seems to be calling callback properly, so not sure exactly what's happening. I did not encounter this issue when I switched over to https://github.com/awslabs/aws-serverless-express.

I'm not sure if this is an intended use case for this library, but if it is I have a snapshot of the code before switching over: https://github.com/hbcwr/pco-schedule-swapper/tree/bookmark/serverless-http.

Serverless Integration Option Support

Hi. Do you have any plans on supporting lambda integration? I would like to use the User Pool as my authentication of the API and I need to specify the integration type as lambda to use the User Pool claims.

Here is my partial serverless.yml definition.

functions:

  # Test API
  test:
    handler: handler.main
    events:
      - http:
          path: / # this matches the base path
          method: ANY
          integration: lambda
          authorizer:
            arn: ${self:custom.userPoolARN}
            claims:
              - custom:organization
              - cognito:groups
      - http:
          path: /{any+} # this matches any path, the token 'any' doesn't mean anything special
          method: ANY
          integration: lambda
          authorizer:
            arn: ${self:custom.userPoolARN}
            claims:
              - custom:organization
              - cognito:groups

Here is my handler file.

'use strict';

import serverless from 'serverless-http';
import express from 'express';

const app = express()

app.get('/', function (req, res) {
  res.send('Hello World!')
})

module.exports.main = serverless(app);

When I try to deploy it using the above configuration, the following output is return on the API Gateway.

{"statusCode":404,"headers":{"x-powered-by":"Express","content-security-policy":"default-src 'self'","x-content-type-options":"nosniff","content-type":"text/html; charset=utf-8","content-length":155},"body":"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET [object%20Object]</pre>\n</body>\n</html>\n"}

does not work with serverless-offline plugin in serverless framework

Hi,

This is a really nice tool and love the idea of just mocking the request and response layers, but, for some reason with serverless-offline plugin in serverless framework i always get empty body in response, also the write function in response object never gets called, (although the assignSocket stub does get all the data).

error defining handler

Your sample code should be as such

const wrapped = serverless(app);
module.exports.handler = async (evt, ctx) => {
    return wrapped(evt, ctx);
}

res.setHeader('Access-Control-Allow-Origin', '*');

How I do to works in all project replace headers response:, I try:

module.exports.handler = serverless(app, {
response: function (response, event, context) {
// Not working
response.headers['Access-Control-Allow-Origin'] = '*';
}
});

But, if I do for each function it works:

function (req, res) {

res.setHeader('Access-Control-Allow-Origin', '*');

res.status(200).json('OK');

}

Can you help me?

How to correctly return binary payload to AWS API Gateway from Lambda

Hello! I am trying to use serverless-http to wrap a Koa image manipulation API and deploy it on AWS Lambda with APIGW. I ran into some problems returning a binary payload so I tried base64 encoding my body response and then do this in the handler:

const serverless = require('serverless-http');
const server = require('./server');

module.exports.handler = serverless(server, {
  request: function(request, event, context) {
    console.log(request);
  },
  response: function(response, event, context) {
    // Set isBase64Encoded true so API gateway knows the body needs to be decoded
    response.isBase64Encoded = true;
    console.log(response);
  }
});

I've setup CloudWatch logging and it correctly logs the response object having the isBase64Encoded field set. However when I invoke the function using awscli I get:

{
  "isBase64Encoded":false,
  "statusCode":200,
  "headers": {...},
  "body": "..."
}

Any ideas why my response modification is not present in the invocation result?

No content-type header for requests checking for cache expiration (304)

If client issues requests with if-modified-since': 'Tue, 01 Jan 1980 00:00:00 GMT'
i.e. to check whether resource have had been updated,
there is no content-type header generated, but binary handler still being called:

  binary: headers => {
    const ct = headers['content-type'];
    if (ct === undefined) {
      console.error("No content-type header: " + JSON.stringify(headers));
      return false;
    }
    return String(ct).match(/text\/.*/) || ct == "application/json" ? false : true;
  },

resulting in multiple errors "No content-type header" in logs/CloudWatch.

getString called with more than 1 argument

In the response object, the code calls getString with 2 arguments:

const string = getString(data, encoding);

But getString only takes 1 argument:
module.exports = function getString(data) {
if (Buffer.isBuffer(data)) {
return data.toString();
} else if (typeof data === 'string') {
return data;
} else {
throw new Error(`response.write() of unexpected type: ${typeof data}`);
}
};

I'm not sure what the original intent was here but it could potentially lead to buggy behavior.

Working with SailsJS?

How can we set this up with SailsJS. Following is my app.js file

var sails = sails = require('sails');
var rc = require('sails/accessible/rc');
const sls = require('serverless-http');

// Start server
sails.lift(rc('sails'));
module.exports.server =  sls(sails);

Throws the following error

{"errorMessage":"Error while loading app","errorType":"Error","stackTrace":["Error: serverless-http only supports koa, express/connect or a generic http listener","at getHandler (/Volumes/SailsApp/node_modules/serverless-http/lib/get-handler.js:16:9)","at module.exports

Image/png is not serving properly by serverless-http

Hi,

Is serverless-http able to serve jpg/png images? I have some image assets that I deployed with my application but it's not rendering the img/png correctly. The content-type shows image/jpeg and it's serving properly, getting 200 but not displaying correctly. Is this an encoding issue.

Any help would be greatly appreciated.

Does not work correctly with inversify-express-utils

Hi,

I was playing around with serverless-http and I love the idea of it!
I did however, find an issue when trying to use inversify-express-utils.

Currently, using serverless-http the only way I can send data to my controllers is through using query strings.
Even when using body-parser as middleware to express, when passing the body into the XHR that goes through serverless-http, it ends up getting to the controller as an empty object ({}).

If I run my server locally without using my configured lambda.ts, I am able to pass data via body to my controllers.

Any ideas on how to solve this issue?

Thanks very much!

Server.ts:
import 'reflect-metadata';
import * as express from 'express';
import { json } from 'body-parser';
import { InversifyExpressServer } from 'inversify-express-utils';
import { InjectModule } from './Injector';

export class Server {
public app: express.Application;
private _server: InversifyExpressServer;

constructor() {
    this._server = new InversifyExpressServer(InjectModule);

    this.app = this._server.setConfig((app) => {
        app.use(json());
    }).build();

    this.app.listen(3000, () => {
        console.log('listening on port 3000');
    });
}

}

lambda.ts:
import { Server } from './Server';
import * as serverless from 'serverless-http';

const server = new Server();

module.exports.handler = serverless(server.app);

AWS custom authorizer support

Hi,

We are using APIG authorizers in our project and they were not working with serverless http, the problem is that parameters coming from APIG authorizers are coming in event.requestContext object, I can do the fixes to current Request object and send a PR.

Suggestion:

in request object the event.requestContext.auhtorizers is mapped to req.authorizers

EDIT: will close this, just figured out that I can use transformers doing this. maybe there could be a more accurate example made thou for using transformers, and that documentation should be put to the front page :)

Cannot pass body with event.json

I have a post method defined in the following way

        app.post('/upload', function (req, res) {
            res.send(req.body);
        }

If i curl the method and pass a json object it works fine. I cannot get it work though with serverless invoke local --path event.json.

Here is my event.json file

  {
        "path": "/upload",
        "httpMethod": "POST",
        "headers": {
                "Content-Type": "application-json"
        },
        "queryStringParameters": null,
        "pathParameters": null,
        "stageVariables": null,
        "body": "{\"image\": \"asdf\"}",
        "isBase64Encoded": false
  }

I also tried giving an object for the body but i get the following error

{
    "errorMessage": "Unexpected event.body type: object",
    "errorType": "Error",
    "stackTrace": [
        "getBody (/var/task/node_modules/serverless-http/lib/request.js:17:9)",
        "new ServerlessRequest (/var/task/node_modules/serverless-http/lib/request.js:29:18)",
        "Promise.resolve.then (/var/task/node_modules/serverless-http/serverless-http.js:30:25)"
    ]
}

How should the body look like in the event.json so that i get a json object inside my handler?

req.connection.address is not a function

I am using the bugsnag error middleware to report errors with Express.
The middleware makes serverless-http crash, as req.connection.address() is not defined.

Maybe serverless-http could implement this method, as other Express/Connect middlewares probably use it?

See bugsnag/bugsnag-node#129 for details about the error.

More detailed example(s)

Can you please provide some more detailed example?
I still don't get how can I define a "catch all" handler in my serverless.yml

Feature Req: Expose event (and maybe context) to the request object

Event can contain important information especially when utilizing custom authorizers. I recommend exposing at least the event on the request object so it can be accessed by middle.

As an example, in our fork of this repo we're doing:

// in lib/request.js
    Object.assign(this, {
      ip: event.requestContext.identity.sourceIp,
      complete: true,
      apiGateway: { event },
      httpVersion: '1.1',
      httpVersionMajor: '1',
      httpVersionMinor: '1',
      method: event.httpMethod,
      headers: headers,
      url: url.format({
        pathname: event.path,
        query: event.queryStringParameters
      })
    });

Support for Google Cloud Functions / Azure Functions

I think it would be great as by supporting all providers this project has the potential to become the one serverless framework to rule them all. I don't know if this would fit the current scope of the project though.

Otherwise I am thinking maybe of making another project using this one as its "lambda" adapter.

Callback is not a function.

using

module.exports.handler = serverless(app);

I get the following error:

2018-03-18T06:08:03.347Z - error: /home/ajmwagar/usr/dev/git/outrigger/node_modules/serverless-http/serverless-http.js:58
        callback(e);
        ^

TypeError: callback is not a function
    at process.nextTick (/home/ajmwagar/usr/dev/git/outrigger/node_modules/serverless-http/serverless-http.js:58:9)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
2018-03-18T06:08:03.355Z - info: Execution took 12 ms, finished with status: 'crash'
2018-03-18T06:08:03.374Z - error: Function worker crashed with exit code: 1

I will look into a fix.

Thanks for maintaining such a great library.

Support for generic request listeners

Right now only express/connect/koa are supported for handling the request. However, I think any function that has a valid signature for http.createServer() should work as a handler.

From quickly looking at the code it could be a simple additional block in getHandler()

if (typeof app === 'function') {
  return app;
}

What do you think?

Missing Request body both Koa and Express

I'm print all ctx but can not find body

serverless:

// index.js

const serverless = require('serverless-http');
var bodyParser = require('koa-bodyparser');
const AWS = require('aws-sdk');
const Router = require('koa-router');
var router = new Router();

const Koa = require('koa');
const app = new Koa();


// register your middleware as normal
app.use(bodyParser());
app
  .use(router.routes())
  .use(router.allowedMethods());

router
  .post('/test', async (ctx, next) => {  
    ctx.body = [{"name": 1, userId: "099999"}, ctx];
  })

module.exports.handler = serverless(app);

request body:
{"userId": 123}
but ctx:

[
 {
   "name": 1,
   "userId": "099999"
 },
 {
   "request": {
     "method": "POST",
     "url": "/test",
     "header": {
       "content-length": 10,
       "x-request-id": "577c76fd-bb37-11e8-8e29-9757c42b128b"
     }
   },
   "response": {
     "status": 200,
     "message": "OK",
     "header": {
       "content-type": "application/json; charset=utf-8"
     }
   },
   "app": {
     "subdomainOffset": 2,
     "proxy": false,
     "env": "development"
   },
   "originalUrl": "/test",
   "req": "<original node req>",
   "res": "<original node res>",
   "socket": "<original node socket>"
 }
]

p/s: using LAMBDA_PROXY

Route not found

Hi.

I love this package. ๐Ÿฅ‡

I'm getting 404 for all endpoints after upgrade to 1.5.4.
The cause is the new way to find the path before pass it to the request (5fc27b2#diff-4f98820926ab9e533c0e3ef619e49f66R10)

The follow line always return '/' because the route is in event.path.

event.requestContext.path = event.requestContext.path || '/';

I moved on with this workaround:

'use strict';

import serverless from 'serverless-http';
import app from './app/main';

export const handler = serverless(app, {
  request: function(request, event, context) {
    if (process.env.IS_OFFLINE) {
      event.requestContext.path = event.path || event.requestContext.path;
      request.url = event.requestContext.path;
    }
  }
});

Did I missed something?

OS: Ubuntu 16.04
NodeJS: v6.9.1
serverless: 1.26.1
serverless-offline: v3.18.0

Configuration option to strip basePath/stage from event.path

The current assumption is that either (for AWS API Gateway):

  1. the app is deployed to / basePath; or
  2. the (express) app will handle both local development (/ path prefix) and remote development paths (/basePath/stage path prefix)

Meaning that by default, an app that works locally or with / basePath will get errors like:

Cannot GET /geo/v1/geoPlaces/findTopCityLikeByPopulation

When deployed to geo:* basePath.

This is similar issue to CodeGenieApp/serverless-express#86 and claudiajs/claudia#170

Currently I use a workaround like this:

module.exports.handler = async (event, context) => {
  // FIXME: Ugly workaround for https://github.com/awslabs/aws-serverless-express/issues/86 and https://github.com/claudiajs/claudia/issues/170
  event.path = event.path.replace(/^\/geo\/v[^/]+/, '')
  return await handler(event, context)
}

It'd be great if this use case can be explicitly supported by a configuration option, or at least, mentioned in the README.md / documentation for AWS provider.

node 6.9.x issue

Hi,

Is this tested on node-6.9.1? I am trying this with a koa-1.4 app, with a simple code that throws a 401 error (this.throw(`Unauthorized: ${this.request.method} ${this.request.url}`, 401);), but this error never reaches the aws lambda service. I always get a timeout error from aws lamda.

Thank you for your help!

Tamas

Expose the original event into the request for the app

It would be nice if the original event from aws, the one that is given to the aws lambda handler, get exposed in the 'HttpRequest' object, so one could have access to it through context.originalEvent, in a koa example.

I had to write a wrapper like this to have access to the original event:

function injectEvent(event, context, callback) {
  const app = new Koa();
  app.context.originalEvent = event;
  serverlessHttp(app)(event, context, callback)
}

I had expected that the framework somehow provided this but it is not the case. Every framework gives us the original http request so I think that's the right place. Well, if I'm wrong please tell me why.

Does not play nice with `multer`

I'm trying to create a little app that processes images of celebrities. I'm utilizing the multer library to handle my image uploads. When tested with only express, the image uploads work great, but when wrapped with serverless-http the image uploads are corrupted. Here is a sample repository that demonstrates the problem. You can test with serverless-offline, but the problem also persists when released to AWS as well. Thanks for any insight you can provide!

How to integrate if you connect to MongoDB (or whatever non-AWS database)

Typically on an HTTP Express setup you would connect to the database before you start listening on a port. But since each request requires a brand new Lambda request, integrating MongoDb requires a connection (possibly cached) to MongoDB per Lambda request.

What is the recommended place in this library to initialize this MongoDB connection before the request is handled?

I was thinking that the MongoDB connection could be injected into the request object via an Express middleware, but I'm not sure if it's a good idea.

No way to access stage variables

We use stage variables to configure remote endpoints that are used by our lambda. Currently there is no way to access those from express using this library.

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.