Git Product home page Git Product logo

saaskit's Introduction

Deno SaaSKit

Discord Chat CI codecov Built with the Deno Standard Library

Deno SaaSKit is an open-sourced, highly performant template for building your SaaS quickly and easily.

Note: this project is in beta. Design, workflows, and user accounts are subject to change.

Features

  • Deno's built-in formatter, linter and test runner and TypeScript support
  • Next-gen web framework with Fresh
  • In-built data persistence with Deno KV
  • High-level OAuth with Deno KV OAuth
  • Modern CSS framework with Tailwind CSS
  • Responsive, SaaS-oriented design
  • Dashboard with users view and statistics chart
  • Stripe integration (optional)
  • First-class web performance
  • REST API
  • Blog with RSS feed and social sharing icons
  • HTTP security headers

Get Started

Get Started Locally

Before starting, you'll need:

  • A GitHub account
  • The Deno CLI and Git installed on your machine

To get started:

  1. Clone this repo:
    git clone https://github.com/denoland/saaskit.git
    cd saaskit
  2. Create a new .env file.
  3. Navigate to GitHub's New OAuth Application page.
  4. Set Application name to your desired application name. E.g. ACME, Inc.
  5. Set Homepage URL to http://localhost:8000.
  6. Set Authorization callback URL to http://localhost:8000/callback.
  7. Click Register application.
  8. Copy the Client ID value to the .env file:
    GITHUB_CLIENT_ID=<GitHub OAuth application client ID>
  9. On the same web page, click Generate a new client secret.
  10. Copy the Client secret value to the .env file on a new line:
    GITHUB_CLIENT_SECRET=<GitHub OAuth application client secret>
  11. Start the server:
    deno task start
  12. Navigate to http://localhost:8000 to start playing with your new SaaS app.

Set Up Stripe (Optional)

This guide will enable test Stripe payments, the pricing page, and "Premium user" functionality.

Before starting, you'll need:

To get started:

  1. Navigate to the API keys page on the Developers dashboard.
  2. In the Standard keys section, click Reveal test key on the Secret key table row.
  3. Click to copy the value and paste to the .env file:
    STRIPE_SECRET_KEY=<Stripe secret key>
  4. Run the Stripe initialization script:
    deno task init:stripe
  5. Copy the Stripe "Premium Plan" price ID to the .env file:
    STRIPE_PREMIUM_PLAN_PRICE_ID=<Stripe "Premium Plan" price ID>
  6. Begin listening locally to Stripe events:
    stripe listen --forward-to localhost:8000/api/stripe-webhooks --events=customer.subscription.created,customer.subscription.deleted
  7. Copy the webhook signing secret to the .env file:
    STRIPE_WEBHOOK_SECRET=<Stripe webhook signing secret>
  8. Start the server:
    deno task start
  9. Navigate to http://localhost:8000 to start playing with your new SaaS app with Stripe enabled.

Note: You can use Stripe's test credit cards to make test payments while in Stripe's test mode.

Bootstrap the Database (Optional)

Use the following commands to work with your local Deno KV database:

  • deno task db:seed - Populate the database with data from the Hacker News API.
  • deno task db:dump > backup.json - Write all database entries to backup.json.
  • deno task db:restore backup.json - Restore the database from backup.json.
  • deno task db:reset - Reset the database. This is not recoverable.

Customize and Extend

Global Constants

The utils/constants.ts file includes global values used across various aspects of the codebase. Update these values according to your needs.

Create a Blog Post

  1. Create a .md file in the /posts with the filename as the slug of the blog post URL. E.g. a file with path /posts/hello-there.md will have path /blog/hello-there.

  2. Write the Front Matter then Markdown text to define the properties and content of the blog post.

    ---
    title: This is my first blog post!
    publishedAt: 2022-11-04T15:00:00.000Z
    summary: This is an excerpt of my first blog post.
    ---
    
    # Heading 1
    
    Hello, world!
    
    ```javascript
    console.log("Hello World");
    ```
  3. Start the server:

    deno task start
  4. Navigate to the URL of the newly created blog post. E.g. http://localhost:8000/blog/hello-there.

See other examples of blog post files in /posts.

Themes

You can customize theme options such as spacing, color, etc. By default, Deno SaaSKit comes with primary and secondary colors predefined within tailwind.config.ts. Change these values to match your desired color scheme.

Cover Image

To replace the cover image, replace the /static/cover.png file. If you'd like to change the filename, also be sure to change the imageUrl property in the <Head /> component.

Deploy to Production

This section assumes that a local development environment is already set up.

  1. Navigate to your GitHub OAuth application settings page.
  2. Set the Homepage URL to your production URL. E.g. https://hunt.deno.land.
  3. Set the Authorization callback URL to your production URL with the /callback path. E.g. https://hunt.deno.land/callback.
  4. Copy all the environment variables in your .env file to your production environment.

Deploy to Deno Deploy

  1. Clone this repository for your SaaSKit project.
  2. Update your .github/workflows/deploy.yml file as needed. Hints are in the file.
  3. Sign into Deno Deploy with your GitHub account.
  4. Click + New Project.
  5. Select your GitHub organization or user, repository, and branch.
  6. Click Edit mode and select Build step with GitHub Actions as the build mode and main.ts as the entry point.
  7. Click Add Build Step and wait until the GitHub Actions Workflow is complete.
  8. Once the deployment is complete, click on Settings and add the production environmental variables, then hit Save.

You should now be able to visit your newly deployed SaaS website.

Deploy to any VPS with Docker

Docker makes it easy to deploy and run your Deno app to any virtual private server (VPS). This section will show you how to do that with AWS Lightsail and Digital Ocean.

  1. Install Docker on your machine, which should also install the docker CLI.
  2. Create an account on Docker Hub, a registry for Docker container images.

Note: the Dockerfile, .dockerignore and docker-compose.yml files come included with this repo.

  1. Grab the SHA1 commit hash by running the following command in the repo's root folder:
# get the SHA1 commit hash of the current branch
git rev-parse HEAD
  1. Copy the output of the above and paste it as DENO_DEPLOYMENT_ID in your .env file. This value is needed to enable caching on Fresh in a Docker deployment.

  2. Finally, refer to these guides for using Docker to deploy Deno to specific platforms:

Set Up Stripe for Production (Optional)

  1. Activate your Stripe account.
  2. Navigate to the API keys page on the Developers dashboard.
  3. In the Standard keys section, click Reveal test key on the Secret key table row.
  4. Click to copy the value and paste to your STRIPE_SECRET_KEY environment variable in your production environment.
    STRIPE_SECRET_KEY=<Stripe secret key>
  5. Navigate to the Webhooks page to register your webhook endpoint.
  6. Click Add endpoint.
  7. Set Endpoint URL to your production URL with the /api/stripe-webhooks path. E.g. https://hunt.deno.land/api/stripe-webhooks.
  8. Set Listen to to Events on your account.
  9. Set customer.subscription.created and customer.subscription.deleted as events to listen to.
  10. Click Add endpoint.
  11. Optionally, set up your Stripe branding to customize the look and feel of your Stripe checkout page.

Google Analytics (Optional)

Set GA4_MEASUREMENT_ID in your production environment to enable Google Analytics.

Note: it is not recommended to set this locally, otherwise your tests and debugging requests will be logged.

REST API Reference

GET /api/items

Get all items in chronological order. Add ?cursor=<cursor> URL parameter for pagination. Limited to 10 items per page.

Example 1:

// https://hunt.deno.land/api/items
{
  "values": [
    {
      "id": "01HAY7A4ZD737BHJKXW20H59NH",
      "userLogin": "Deniswarui4",
      "title": "czxdczs",
      "url": "https://wamufx.co.ke/",
      "score": 0
    },
    {
      "id": "01HAD9KYMCC5RS2FNPQBMYFRSK",
      "userLogin": "jlucaso1",
      "title": "Ok",
      "url": "https://github.com/jlucaso1/crunchyroll-quasar",
      "score": 0
    },
    {
      "id": "01HA7YJJ2T66MSEP78NAG8910A",
      "userLogin": "BrunoBernardino",
      "title": "LockDB: Handle process/event locking",
      "url": "https://lockdb.com",
      "score": 2
    }
    // 7 more items...
  ],
  "cursor": "AjAxSDdUNTBBUkY0QzhEUjRXWjkyVDJZSFhZAA=="
}

Example 2 (using cursor field from page 1):

// https://hunt.deno.land/api/items?cursor=AjAxSDdUNTBBUkY0QzhEUjRXWjkyVDJZSFhZAA==
{
  "values": [
    {
      "id": "01H777YG17VY8HANDHE84ZXKGW",
      "userLogin": "BrunoBernardino",
      "url": "https://asksoph.com",
      "title": "Ask Soph about a dead philosopher",
      "score": 2
    },
    {
      "id": "01H6RG2V3AV82FJA2VY6NJD9EP",
      "userLogin": "retraigo",
      "url": "https://github.com/retraigo/appraisal",
      "title": "Appraisal: Feature Extraction, Feature Conversion in TypeScript",
      "score": 0
    },
    {
      "id": "01H64TZ3TNKFWS35MJ9PSGNWE1",
      "userLogin": "lambtron",
      "url": "https://www.zaynetro.com/post/2023-how-deno-works",
      "title": "How Deno works (blog post)",
      "score": 2
    }
    // 7 more items...
  ],
  "cursor": "AjAxSDJUSlBYWUJRM1g0OEo2UlIzSFgyQUQ0AA=="
}

GET /api/items/:id

Get the item with the given ID.

Example:

// https://hunt.deno.land/api/items/01H5379J1VZ7EB54KSCSQSCRJC
{
  "id": "01H5379J1VZ7EB54KSCSQSCRJC",
  "userLogin": "lambtron",
  "url": "https://github.com/Savory/saaskit-danet",
  "title": "saaskit-danet: a modern SaaS template built for Fresh for SSR and Danet for the API",
  "score": 10
}

GET /api/users

Get all users in alphabetical order by GitHub login. Add ?cursor=<cursor> URL parameter for pagination. Limited to 10 users per page.

Example 1:

// https://hunt.deno.land/api/users
{
  "values": [
    {
      "login": "51chengxu",
      "sessionId": "9a6745a1-3a46-45c8-a265-c7469ff73678",
      "isSubscribed": false,
      "stripeCustomerId": "cus_OgWU0R42bolJtm"
    },
    {
      "login": "AiridasSal",
      "sessionId": "adb25cac-9be7-494f-864b-8f05b80f7168",
      "isSubscribed": false,
      "stripeCustomerId": "cus_OcJW6TadIjjjT5"
    },
    {
      "login": "ArkhamCookie",
      "stripeCustomerId": "cus_ObVcWCSYwYOnWS",
      "sessionId": "fd8e7aec-2701-44ae-925b-25e17ff288c4",
      "isSubscribed": false
    }
    // 7 more users...
  ],
  "cursor": "AkVob3ItZGV2ZWxvcGVyAA=="
}

Example 2 (using cursor field from page 1):

// https://hunt.deno.land/api/users?cursor=AkVob3ItZGV2ZWxvcGVyAA==
{
  "values": [
    {
      "login": "EthanThatOneKid",
      "sessionId": "ae7425c1-7932-412a-9956-e456787d557f",
      "isSubscribed": false,
      "stripeCustomerId": "cus_OeYA2oTJRlZBIA"
    },
    {
      "login": "Fleury99",
      "sessionId": "2e4920a3-f386-43e1-8c0d-61b5e0edfc0d",
      "isSubscribed": false,
      "stripeCustomerId": "cus_OcOUJAYmyxZlDR"
    },
    {
      "login": "FriendlyUser",
      "stripeCustomerId": "cus_ObLbqu5gxp0qnl",
      "sessionId": "508ff291-7d1c-4a67-b19f-447ad73b5914",
      "isSubscribed": false
    }
    // 7 more users...
  ],
  "cursor": "Ak5ld1lhbmtvAA=="
}

GET /api/users/:login

Get the user with the given GitHub login.

Example:

// https://hunt.deno.land/api/users/hashrock
{
  "login": "hashrock",
  "stripeCustomerId": "cus_ObqbLXkRtsKy70",
  "sessionId": "97eec97a-6636-485e-9b14-253bfa3ce1de",
  "isSubscribed": true
}

Goals and Philosophy

For the user, the website should be fast, secure and have a design with clear intent. Additionally, the HTML should be well-structured and indexable by search engines. The defining metrics for these goals are:

For the developer, the codebase should minimize the steps and amount of time required to get up and running. From there, customization and extension of the web app should be simple. The characteristics of a well-written codebase also apply, such as:

  • Easy to understand
  • Modular functionality
  • Clearly defined behavior with validation through tests

Community and Resources

Join the #saaskit channel in Deno's Discord to meet other SaaSKit developers, ask questions, and get unblocked.

Here's a list of articles, how to guides, and videos about SaaSKit:

saaskit's People

Contributors

azohra avatar boscohyun avatar bqrkhn avatar brunocorrea23 avatar cdoremus avatar deer avatar dependabot[bot] avatar digioak avatar harshmangalam avatar hashrock avatar huai-jie avatar inverted-capital avatar iuioiua avatar jabolol avatar lambtron avatar lino-levan avatar mbhrznr avatar nicu-chiciuc avatar niklasmtj avatar niranjan-kurhade avatar revgum avatar roberto-morado avatar rroblf01 avatar ryanponce avatar smitssjors avatar thorwebdev avatar vicky-gonsalves avatar vladimircreator avatar zaynetro avatar zzeleznick 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

saaskit's Issues

Incorrect email in Stripe checkout

Hey, I assume there's some code in this repo that helps pre-fill the Stripe email. If I sign up to saaskit with a new user, I see the Stripe email is of a previous/old user:

image

Event type not supported: customer.subscription.updated

If I cancel a subscription from Stripe, I'm seeing

Event type not supported: customer.subscription.updated

Does that need to be handled, or is it only customer.subscription.deleted that matters? Presumably, when the subscription period has ended, customer.subscription.deleted is then sent, even if the sub was already cancelled. If so, I guess this makes sense!

Feature request: docs at deno.com/saaskit/docs

Is your feature request related to a problem? Please describe.

would love to have a dedicated home for SaaSKit specific documentation. i think deno.com/saaskit/docs is a good place. the docs would cover everything from getting setup to how to extend functionality.

Describe the solution you'd like A clear and concise description of what you
want to happen.

here's a loose outline. we can do it similar to https://deno.com/deploy/docs

i tried to be exhaustive in the below outline but some of those sections currently may not be pertinent (e.g. organizations). i think we start small and add as we go.

- Getting Setup
    - Introduction
    - Cloning the Repo
    - Running locally
- Configuration
    - Global constants
- Architecture
    - Where everything is and why
    - How to structure your SaaS app
    - Data model
- Authentication
    - Supabase Configuration
        - Adding new authentication strategies
- Database and APIs
    - Connecting to a database
    - Writing data
    - Fetching data
    - Uploading blob data
- Development
    - Useful `deno task` commands
    - Contributing to SaaSKit
        - link to Deno style guide
- Payments
    - Configuring Stripe
    - One Time Payments
    - Stripe Webhooks
- Organizations
    - Introduction
    - Extending Organizations
    - Permissions
- Themes
    - Extending current theme with Tailwind
    - Adding your own UI kit to Fresh
    - Creating your own theme
- Testing
    - Writing and Running Tests
- Deployment
    - Deno Deploy
    - Any VPS via Docker

thoughts?

proposal: upvote functionality

#106 is missing upvote functionality. This can be done by having the โ–ฒ be a button that sends a fetch request to /api/vote once clicked, where a table row will be created in a votes table. The votes table will have two columns, user_id and item_id. The rest is self-explanatory.

The status of this button will correlate to whether there is a match for both the logged-in user and the current item ID in the votes table.

The main feed should also sort by amount of votes, from most to least, and display each item's score.

bug: no warning shown when user enters password w/ less than 6 characters on signup

No warning is shown on the UI when the user tries to sign up using a password with less than 6 characters

There is currently a proper Error URL (http://localhost:8000/signup?error=Password%20should%20be%20at%20least%206%20characters), but the signup route doesn't handle it well.

On the signup round there is already a place to handle errors, but it's currently only handling the "User already registered" error

{errorMessage === "User already registered" && (
{errorMessage}
)}

fix: manage subscription

The manage subscription shows the customer portal when it should provide subscription options.

proposal: comment system

Let's make these comments non-nested to begin with. We can implement nested comments in the future if there's enough demand.

Feature request: type-check in CI

Is your feature request related to a problem? Please describe.
Currently, type errors fall through the cracks in CI.

Describe the solution you'd like
A new step in the current CI that uses deno check main.ts or similar.

Not setting own premium plan price id results in a 500 error at stripe

After setting up a new project following the README i found that not setting the STRIPE_PREMIUM_PLAN_PRICE_ID in constants.ts to my created premium plan resulting in the following error:

Server error

500 internal error: No such price: 'price_1MPiEkD6QJts4RaYcp1SevPe'

The price id mentioned is the one that is preconfigured in the constants.ts. Maybe updating the Customizing Deno SaaSKit section in README to give a heads up might help preventing this error.

However setting the mentioned STRIPE_PREMIUM_PLAN_PRICE_ID variable to an empty string "" in constants.ts will result in a differend error:

500 internal error: You passed an empty string for 'line_items[0][price]'. We assume empty values are an attempt to unset a parameter; however 'line_items[0][price]' cannot be unset. You should remove 'line_items[0][price]' from your request or supply a non-empty value.

So first I would suggest updating the README to make sure that a new starter can find the solution there.

public roadmap

in github repos that show a public roadmap, where is that usually put? projects? discussion? we should add one and link to it often.

proposal: dynamic header menu

#106 is missing a dynamic header menu. Currently, it doesn't change depending on whether the user is logged in. Spec:

  1. Logout link moved to a button on the account page
  2. Blog menu item moved to the site footer
  3. Menu has "Account" link when logged in. Otherwise, has a "Login" link.
  4. Submit link looks pretty.

proposal: showcase

It'd be nice to have a showcase similar to Fresh's or Deno's for projects that somehow use building blocks from Deno SaaSKit. Such projects would offer further examples of how Deno SaaSKit can be customized, chopped and changed to suit different needs.

I think we'll have to have a minimum of 3 projects to start. First in, best dressed.

todo: rework HTTP redirects

Spec:

  • A HTTP redirect helper function for relative paths like redirect(path: string, status: 300 | 301...) => Response
  • The HTTP redirects across the codebase were done without much thought from me and likely need to be corrected.

Docker is an implicit dependency?

Describe the bug A clear and concise description of what the bug is.

When running npx supabase start from the setup guide, I get: Error: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

To Reproduce Steps to reproduce the behavior:

  1. Clone this project
  2. Copy .env.example to .env
  3. Run npx supabase start

Expected behavior A clear and concise description of what you expected to
happen.

The setup guide should state all setup dependencies.

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS] macOS
  • Browser [e.g. chrome, safari] N/A
  • Version [e.g. 22] I don't know how to tell that in Deno?

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context Add any other context about the problem here.

Pages are sometimes very slow to load

For example, can't explain why, but if you add more logging, that might be handy!

image

Hard to reproduce, but am curious what's happening under the hood to cause >10 second response times.

Bug report: GitHub oauth redirects to localhost:3000 in demo

Describe the bug
in the demo, https://saaskit.deno.dev, if you auth via github, you are redirected to localhost:3000

To Reproduce Steps to reproduce the behavior:

  1. Go to https://saaskit.deno.dev/signup
  2. Click on 'Login with GitHub'
  3. See error (you'll end up on localhost:3000)

Expected behavior
You should end up on https://saaskit.deno.dev/dashboard.

Screenshots If applicable, add screenshots to help explain your problem.
image

Desktop (please complete the following information):
Chrome

proposal: design decision notes

It's essential that we, as maintainers and users, understand the reasons behind our design decisions. I'd like to include notes on these design decisions and architectural details in the codebase. We can do so via JSDoc comments within the code or in the README. I'm leaning towards JSDoc comments right now. Either way, aspects worth talking about include the following:

  • Blog
  • Database
  • Formatting
  • Fresh
  • Linting
  • Payments
  • Testing

Feature request: `<Meta />` component

Is your feature request related to a problem? Please describe.
The blog, including the index and individual posts, has meta tags, which are a strong base for future meta tags support but are manually written.

Describe the solution you'd like
A <Meta /> component that can be reused anywhere on the website.

Additional context
Spec:

  • <Meta /> component with reasonable defaults and properties such as title, description, etc.
  • Comments sectioning meta tags by platform. For example, see this and click Generate.
  • Add the new component wherever applicable on the website.

Bug: Cannot read properties of null (reading 'email') while signup

Hi, I'm using SaaSKit. It's a brilliant example of what I'm looking to do with Deno. Thanks for the great work!!

Getting this error 500 internal error: Cannot read properties of null (reading 'email') while signup.
Auth looks good in my configured Supabse but the customers table is empty.

The error occurred during this line because of empty user data.

Maybe it's an issue from Supabase?

Documentation update request: Supabase setup

In the root README.md, it has steps to do in Supabase, and it seems like those changes happen in two different dashboards. There's a local server (is it a local instance of Supabase?) at http://localhost:54323 with a Supabase dashboard, and I guess there's a dashboard representing the Supabase account we just set up.

The documentation is very vague about which thing to do where. It suggests that tables are set up in the local dashboard, but then goes on to describe steps that presumably can only happen in app.supabase.com because that's the only place where those menu items exist (like for authentication).

Can you please say which steps to do locally, and which steps to do remotely, since they are two very similar dashboards?

proposal: user display names

This can be a unique username or a non-unique display name for each user. It's worth ignoring what Hacker News or Product Hunt does here and instead asking which is better.

We should use a new table if it's to be a unique username. If it's to be a non-unique display name, it might be better to come from the user_metadata object.

I'd like to hear some thoughts.

CC @lambtron and @thorwebdev

Roadmap

This issue exists as a continually growing roadmap for SaaSKit. The eventual goal is to provide a framework where developers can launch a SaaS app in a single afternoon (aka cloning this repo, making the necessary adjustments in the code, and then deploying it). Here are items that I think we'll need to get there.

v1

Post v1

  • #72
  • #73
  • add UI theme system with a library of at least 3 themes to start. These themes should include a blog, landing page, /dashboard, and user profile
  • add error monitoring and observability (we can select a popular observability tool for this... telemetry?)
  • add multi-factor authentication via SMS/Authy
  • add simple email capture or newsletter integration

Open to discussion as well, so feel free to leave your thoughts below.

feature: add meta tags to blog

To enable OpenGraph descriptions, pictures etc. we should also add the most important meta tags to the blog landing and post pages. What do you think?

update readme

basically make the readme very thorough and cover:

what this is (marketing copy)
how to get started/setup
links to deno.com/blog, deno.com/saaskit, relevant youtube videos, discord if they're stuck
direct users to issues for feedback

Feature request: CLI installation command

Is your feature request related to a problem? Please describe.

would be cool to scaffold a SaaSKit project with a command like:

deno run -A -r https://deno.com/saaskit my-project

see Fresh for example:
https://github.com/denoland/fresh/blob/main/www/routes/index.tsx#L15
https://github.com/denoland/fresh/blob/main/init.ts

Describe the solution you'd like A clear and concise description of what you
want to happen.

also this script doesn't need to be on deno.com/saaskit... it could be something else. saaskit.deno.dev? open to ideas.

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.