Giter VIP home page Giter VIP logo

ladder's Introduction

Ladder

License go.mod Go version GitHub tag (with filter) GitHub (Pre-)Release Date GitHub Downloads all releases GitHub Build Status (with event)

Ladder is a web proxy to help bypass paywalls. This is a selfhosted version of 1ft.io and 12ft.io. It is inspired by 13ft.

Why

Freedom of information is an essential pillar of democracy and informed decision-making. While media organizations have legitimate financial interests, it is crucial to strike a balance between profitability and the public's right to access information. The proliferation of paywalls raises concerns about the erosion of this fundamental freedom, and it is imperative for society to find innovative ways to preserve access to vital information without compromising the sustainability of journalism. In a world where knowledge should be shared and not commodified, paywalls should be critically examined to ensure that they do not undermine the principles of an open and informed society.

Disclaimer: This project is intended for educational purposes only. The author does not endorse or encourage any unethical or illegal activity. Use this tool at your own risk.

How it works

sequenceDiagram
    client->>+ladder: GET
    ladder-->>ladder: apply RequestModifications
    ladder->>+website: GET
    website->>-ladder: 200 OK
    ladder-->>ladder: apply ResultModifications
    ladder->>-client: 200 OK

Features

  • Bypass Paywalls
  • Remove CORS headers from responses, assets, and images ...
  • Apply domain based ruleset/code to modify response / requested URL
  • Keep site browsable
  • API
  • Fetch RAW HTML
  • Custom User Agent
  • Custom X-Forwarded-For IP
  • Docker container (amd64, arm64)
  • Linux binary
  • Mac OS binary
  • Windows binary (untested)
  • Removes most of the ads (unexpected side effect ¯\_(ツ)_/¯ )
  • Basic Auth
  • Disable logs
  • No Tracking
  • Limit the proxy to a list of domains
  • Expose Ruleset to other ladders
  • Fetch from Google Cache
  • Optional TOR proxy
  • A key to share only one URL

Limitations

Some sites do not expose their content to search engines, which means that the proxy cannot access the content. A future version will try to fetch the content from Google Cache.

Certain sites may display missing images or encounter formatting issues. This can be attributed to the site's reliance on JavaScript or CSS for image and resource loading, which presents a limitation when accessed through this proxy. If you prefer a full experience, please consider buying a subscription for the site.

Installation

Warning: If your instance will be publicly accessible, make sure to enable Basic Auth. This will prevent unauthorized users from using your proxy. If you do not enable Basic Auth, anyone can use your proxy to browse nasty/illegal stuff. And you will be responsible for it.

Binary

  1. Download binary here
  2. Unpack and run the binary ./ladder -r https://t.ly/14PSf
  3. Open Browser (Default: http://localhost:8080)

Docker

docker run -p 8080:8080 -d --env RULESET=https://t.ly/14PSf --name ladder ghcr.io/everywall/ladder:latest

Docker Compose

curl https://raw.githubusercontent.com/everywall/ladder/main/docker-compose.yaml --output docker-compose.yaml
docker-compose up -d

Helm

See README.md in helm-chart sub-directory for more information.

Usage

Browser

  1. Open Browser (Default: http://localhost:8080)
  2. Enter URL
  3. Press Enter

Or direct by appending the URL to the end of the proxy URL: http://localhost:8080/https://www.example.com

Or create a bookmark with the following URL:

javascript:window.location.href="http://localhost:8080/"+location.href

API

curl -X GET "http://localhost:8080/api/https://www.example.com"

RAW

http://localhost:8080/raw/https://www.example.com

Running Ruleset

http://localhost:8080/ruleset

Configuration

Environment Variables

Variable Description Value
PORT Port to listen on 8080
PREFORK Spawn multiple server instances false
USER_AGENT User agent to emulate Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
X_FORWARDED_FOR IP forwarder address 66.249.66.1
USERPASS Enables Basic Auth, format admin:123456 ``
LOG_URLS Log fetched URL's true
DISABLE_FORM Disables URL Form Frontpage false
FORM_PATH Path to custom Form HTML ``
RULESET Path or URL to a ruleset file, accepts local directories https://raw.githubusercontent.com/everywall/ladder-rules/main/ruleset.yaml or /path/to/my/rules.yaml or /path/to/my/rules/
EXPOSE_RULESET Make your Ruleset available to other ladders true
ALLOWED_DOMAINS Comma separated list of allowed domains. Empty = no limitations ``
ALLOWED_DOMAINS_RULESET Allow Domains from Ruleset. false = no limitations false

ALLOWED_DOMAINS and ALLOWED_DOMAINS_RULESET are joined together. If both are empty, no limitations are applied.

Ruleset

It is possible to apply custom rules to modify the response or the requested URL. This can be used to remove unwanted or modify elements from the page. The ruleset is a YAML file, a directory with YAML Files, or an URL to a YAML file that contains a list of rules for each domain. These rules are loaded on startup.

There is a basic ruleset available in a separate repository ruleset.yaml. Feel free to add your own rules and create a pull request.

- domain: example.com          # Includes all subdomains
  domains:                     # Additional domains to apply the rule
    - www.example.de
    - www.beispiel.de
  headers:
    x-forwarded-for: none      # override X-Forwarded-For header or delete with none
    referer: none              # override Referer header or delete with none
    user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
    content-security-policy: script-src 'self'; # override response header
    cookie: privacy=1
  regexRules:
    - match: <script\s+([^>]*\s+)?src="(/)([^"]*)"
      replace: <script $1 script="/https://www.example.com/$3"
  injections:
    - position: head # Position where to inject the code
      append: |      # possible keys: append, prepend, replace
        <script>
          window.localStorage.clear();
          console.log("test");
          alert("Hello!");
        </script>
- domain: www.anotherdomain.com # Domain where the rule applies
  paths:                        # Paths where the rule applies
    - /article
  googleCache: false            # Use Google Cache to fetch the content
  regexRules:                   # Regex rules to apply
    - match: <script\s+([^>]*\s+)?src="(/)([^"]*)"
      replace: <script $1 script="/https://www.example.com/$3"
  injections:
    - position: .left-content article .post-title # Position where to inject the code into DOM
      replace: | 
        <h1>My Custom Title</h1>
    - position: .left-content article # Position where to inject the code into DOM
      prepend: | 
        <h2>Subtitle</h2>
- domain: demo.com
  headers:
    content-security-policy: script-src 'self';
    user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
  urlMods:              # Modify the URL
    query:              
      - key: amp        # (this will append ?amp=1 to the URL)
        value: 1 
    domain:             
      - match: www      # regex to match part of domain
        replace: amp    # (this would modify the domain from www.demo.de to amp.demo.de)
    path:               
      - match: ^        # regex to match part of path
        replace: /amp/  # (modify the url from https://www.demo.com/article/ to https://www.demo.de/amp/article/)

Development

To run a development server at http://localhost:8080:

echo "dev" > handlers/VERSION
RULESET="./ruleset.yaml" go run cmd/main.go

Optional: Live reloading development server with cosmtrek/air

Install air according to the installation instructions.

Run a development server at http://localhost:8080:

air # or the path to air if you haven't added a path alias to your .bashrc or .zshrc

This project uses pnpm to build a stylesheet with the Tailwind CSS classes. For local development, if you modify styles in form.html, run pnpm build to generate a new stylesheet.

ladder's People

Contributors

boomam avatar deoxykev avatar dxbednarczyk avatar giannicarafa avatar jgillies avatar joncrangle avatar ladddder avatar lutfuahmet avatar mms-gianni avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ladder's Issues

May I inquire about the method to enable a program to establish a network connection via a proxy?

I consistently encounter the following error message while attempting to access content, and I suspect it may be due to a network firewall. I am utilizing a binary program for this purpose.

2023/11/13 16:54:28 ERROR: Get "https://medium.com/mapresearch/does-the-fourth-industrial-revolution-have-a-new-path-818723d06030": dial tcp 104.244.46.165:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

Idea: API should return structured article json

Using some “reading mode” algorithm (such as DOM-distiller) I think the API could return a json blob representing just the source URL, title, author, date and text content of the article, without the extra HTML.

This would make it feasible for web scraping tasks, for non-JS heavy sites.

In addition, this would open up the possibility of an endpoint that returned the cleaned content of the site, much like the old outline.org.

To deploy on my own VPS

I tried to deploy on my own VPS and changed the port number to 8211 (and I have already opened the firewall). But after the deployment was successful (the Docker logs show normal), I cannot open the work page by entering http://vpsaddress:8211 in the browser's address bar. When deploying with Docker, is it only possible to use port 8080?

Thx in advance

Should Ladder's UI behave differently for mobile?

[Oh just noticed you have Discussions - feel free to move this there, sorry.]

If you use Ladder on a mobile device, it's a bit fiddly to paste your desired URL into the field. At least, on my device you have to work out how to invoke the keyboard after pasting the URL into the form so that you can submit it.

Might it be an idea to show a button on the screen (when in a viewport less than a certain size) that pastes what's in the clipboard into the field, and submits the form?

There may of course be other approaches. BTW I note that the bookmarklet trick doesn't seem to work on mobile as far as I can tell.

Better default theme and auto dark/light theme switching

Hey y'all, I've designed a pretty simple tailwindCSS theme that I think might fit better as a default theme for ladder compared to the current one. It's fairly simple like the original so adding any buttons or text boxes are just as easy as before, but now it uses all tailwind classes.

image
image
image

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>ladder</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>

<body class="antialiased text-slate-500 dark:text-slate-400 bg-white dark:bg-slate-900">
    <div class="grid grid-cols-1 gap-4 max-w-3xl mx-auto pt-10">
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="250" viewBox="0 0 512 512">
            <path fill="#7AA7D1" d="M262.074 485.246C254.809 485.265 247.407 485.534 240.165 484.99L226.178 483.306C119.737 468.826 34.1354 383.43 25.3176 274.714C24.3655 262.975 23.5876 253.161 24.3295 241.148C31.4284 126.212 123.985 31.919 238.633 24.1259L250.022 23.8366C258.02 23.8001 266.212 23.491 274.183 24.1306C320.519 27.8489 366.348 45.9743 402.232 75.4548L416.996 88.2751C444.342 114.373 464.257 146.819 475.911 182.72L480.415 197.211C486.174 219.054 488.67 242.773 487.436 265.259L486.416 275.75C478.783 352.041 436.405 418.1 369.36 455.394L355.463 462.875C326.247 477.031 294.517 484.631 262.074 485.246ZM253.547 72.4475C161.905 73.0454 83.5901 144.289 73.0095 234.5C69.9101 260.926 74.7763 292.594 83.9003 317.156C104.53 372.691 153.9 416.616 211.281 430.903C226.663 434.733 242.223 436.307 258.044 436.227C353.394 435.507 430.296 361.835 438.445 267.978C439.794 252.442 438.591 236.759 435.59 221.5C419.554 139.955 353.067 79.4187 269.856 72.7052C264.479 72.2714 258.981 72.423 253.586 72.4127L253.547 72.4475Z"/>
            <path fill="#7AA7D1" d="M153.196 310.121L133.153 285.021C140.83 283.798 148.978 285.092 156.741 284.353L156.637 277.725L124.406 278.002C123.298 277.325 122.856 276.187 122.058 275.193L116.089 267.862C110.469 260.975 103.827 254.843 98.6026 247.669C103.918 246.839 105.248 246.537 111.14 246.523L129.093 246.327C130.152 238.785 128.62 240.843 122.138 240.758C111.929 240.623 110.659 242.014 105.004 234.661L97.9953 225.654C94.8172 221.729 91.2219 218.104 88.2631 214.005C84.1351 208.286 90.1658 209.504 94.601 209.489L236.752 209.545C257.761 209.569 268.184 211.009 285.766 221.678L285.835 206.051C285.837 197.542 286.201 189.141 284.549 180.748C280.22 158.757 260.541 143.877 240.897 135.739C238.055 134.561 232.259 133.654 235.575 129.851C244.784 119.288 263.680 111.990 277.085 111.105C288.697 109.828 301.096 113.537 311.75 117.703C360.649 136.827 393.225 183.042 398.561 234.866C402.204 270.253 391.733 308.356 367.999 335.1C332.832 374.727 269.877 384.883 223.294 360.397C206.156 351.388 183.673 333.299 175.08 316.6C173.511 313.551 174.005 313.555 170.443 313.52L160.641 313.449C158.957 313.435 156.263 314.031 155.122 312.487L153.196 310.121Z"/>
        </svg>
        <header>
            <h1 class="text-center text-3xl sm:text-4xl font-extrabold text-slate-900 tracking-tight dark:text-slate-200">ladddddddder</h1>
        </header>
        <form id="inputForm" method="get" class="mx-4">
            <div>
                <input type="text" id="inputField" placeholder="Proxy Search" name="inputField" class="w-full text-sm leading-6 text-slate-400 rounded-md ring-1 ring-slate-900/10 shadow-sm py-1.5 pl-2 pr-3 hover:ring-slate-300 dark:bg-slate-800 dark:highlight-white/5 dark:hover:bg-slate-700" required>
            </div>
        </form>
        <footer class="mt-10 text-center text-slate-600 dark:text-slate-400">
            <p>
                Code Licensed Under GPL v3.0 |
                <a href="https://github.com/kubero-dev/ladder" class="hover:text-blue-500 hover:underline underline-offset-2 transition-colors duration-300">View Source</a> |
                <a href="https://www.kubero.dev/" class="hover:text-blue-500 hover:underline underline-offset-2 transition-colors duration-300">kubero.dev</a>
            </p>
        </footer>
    </div>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            M.AutoInit();
        });
        document.getElementById('inputForm').addEventListener('submit', function (e) {
            e.preventDefault();
            let url = document.getElementById('inputField').value;
            if (url.indexOf('http') === -1) {
                url = 'https://' + url;
            }
            window.location.href = '/' + url;
            return false;
        });
    </script>

    <style>
        @media (prefers-color-scheme: light) {
            body {
                background-color: #ffffff;
                color: #333333;
            }
        }

        @media (prefers-color-scheme: dark) {
            body {
                background-color: #1a202c;
                color: #ffffff;
            }
        }
    </style>
</body>

</html>

Cannot run with docker - open /var/lib/docker/tmp/buildkit-mount669939737/Dockerfile: no such file or directory

Trying to run the service on Ubuntu 21.10, using Docker version 20.10.12, build e91ed57.

I get this error:

~/dev  curl https://raw.githubusercontent.com/kubero-dev/ladder/main/docker-compose.yaml --output docker-compose.yaml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   707  100   707    0     0   3399      0 --:--:-- --:--:-- --:--:--  3432
☁  ~/dev  docker-compose up
WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
Creating network "dev_default" with the default driver
Building ladder
[+] Building 0.1s (2/2) FINISHED                                                                                                                                                                                                                                                          
 => [internal] load build definition from Dockerfile                                                                                                                                                                                                                                 0.1s
 => => transferring dockerfile: 2B                                                                                                                                                                                                                                                   0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                                                                    0.0s
 => => transferring context: 2B                                                                                                                                                                                                                                                      0.0s
failed to solve with frontend dockerfile.v0: failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount669939737/Dockerfile: no such file or directory
ERROR: Service 'ladder' failed to build

Request Header Fields Too Large

Hi, I am running ladder behind a traefik reverse proxy with an Authentik ForwardAuth middleware.
When I open the app to the base url, I get the following error: Request Header Fields Too Large
None of my other forwardauth applications experience this. Is it something in my configuration possibly?

Chrome console returns this: Failed to load resource: the server responded with a status of 431 ()

I am running ladder in a container

Idea: break rulesets out into subdirectories and separate files

I think the list of rulset modifications will grow very large over time. Just check out what happened to magnolia1234's bypass-paywalls-firefox-clean ruleset. There are over 1000 individual domains.

A single file would be difficult to maintain.

I propose the ability to fetch rulesets from an open directory, so that they could be organized better.

For example:

rulesets
├── de
│  └── tagesspiegel-de.yaml
├── it
└── us
   └── nytimes.yaml

Idea: Native macOS menu bar desktop app

As an example, here is what the AdGuardHome macOS menu bar looks like:
screenshot_2023-11-06_at_19 53 21@2x

Turning the app "on" would:

  1. Start ladder
  2. Set the macOS system proxy to use ladder

Turning the app "off" would:

  1. Unset the macOS system proxy
  2. Stop ladder

Thoughs? 😄

Cloudlfare again

Cloudflare is blocking again. I tried to change the user agent, then I get the paywal. With the default settings I get blocked.

ladder: 0.0.17
Test-URL: tagesspiegel.de
Screenshot:

grafik

Could someone explain how the problem can be solved with the ruleset? Then I can try to find a solution myself.

unsupported protocol scheme ""

Using an article from New Yorker, I am noticing in the terminal many errors reported in the form:

2023/11/06 16:08:36 GET /verso/static/assets/fonts/TNYAdobeCaslonPro-SemiBoldItalic.woff2
2023/11/06 16:08:36 ERROR: Get "verso/static/assets/fonts/TNYAdobeCaslonPro-SemiBoldItalic.woff2": unsupported protocol scheme ""

I haven't looked at the code yet and wondering what the error means.

Cloudflare blocked

When I try something like:

https://ladder.mydomain.com/https://medium.com/mapresearch/does-the-fourth-industrial-revolution-have-a-new-path-818723d06030

I get:

Sorry, you have been blocked
You are unable to access medium.com

Why have I been blocked?
This website is using a security service to protect itself from online attacks. The action you just performed triggered the security solution. There are several actions that could trigger this block including submitting a certain word or phrase, a SQL command or malformed data.

What can I do to resolve this?
You can email the site owner to let them know you were blocked. Please include what you were doing when this page came up and the Cloudflare Ray ID found at the bottom of this page.

From Cloudflare.


I'm using the following docker-compose config:

version: '3'
services:
  ladder:
    image: ghcr.io/kubero-dev/ladder:latest
    container_name: ladder
    build: .
    #restart: always
    #command: sh -c ./ladder
    environment:
      - PORT=8080
      #- PREFORK=true
      #- X_FORWARDED_FOR=66.249.66.1
      #- USER_AGENT=Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
      #- USERPASS=foo:bar
      #- LOG_URLS=true
      #- GODEBUG=netdns=go
    ports:
      - "8080:8080"
    deploy:
      resources:
        limits:
          cpus: "0.50"
          memory: 512M
        reservations:
          cpus: "0.25"
          memory: 128Mroot@ladder01:/opt# docker-compose up -d

Do you know of a workaround for Cloudflare?

Looking for the curl --compressed equivalent in Ladder

Hi!!

First of all, thanks for this project!

I'm getting 403 error from a website, which I can connect to using CURL. I added the user-agent and all the required headers to my custom ruleset.yaml and it's still failing.

My rule:

- domain: mydomain.com
  headers:
    user-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:121.0) Gecko/20100101 Firefox/121.0
    accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    accept-language: en-US;q=0.7,en;q=0.3

My curl command:

curl https://mywebsite.com/xyz --compressed -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:121.0) Gecko/20100101 Firefox/121.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' -H 'Accept-Language: en-US;q=0.7,en;q=0.3'

If I remove --compressed from Curl then I get the 403 unauthorized. It might be like an anti-bot measure? Does it make sense? If yes, how can I enable "compressed" in Ladder?

Thanks!!

Timeout

Hello, I've just installed ladder on my synology, ladder launches correctly https://mysyno.dsmynas.com.
But as soon as I add a link to a journal I get a timeout.

Get "https://www.lavoixdunord.fr/": dial tcp: lookup www.lavoixdunord.fr on 127.0.0.11:53: read udp 127.0.0.1:59926->127.0.0.11:53: i/o timeout

IMG_2282

IMG_2281

A list of rulesets / Hosting the default rule

Do you have a good ruleset you want to share?
Leave a link here. Ill add it to the README.md

I am looking for a person hosting the default ruleset (Here on Github under GPLv3 or MIT) . Is anyone interested in maintaining it?

Some environment variables are ignored

The docker container (created via docker-compose) ignores at least the following env variables:

LOG_URLS=false
PREFORK=true

docker log:

docker-compose up
[+] Building 0.0s (0/0)
[+] Running 1/0
 ✔ Container ladder  Created                                                       0.0s
Attaching to ladder
ladder  | 2023/11/08 11:08:36 Loading rules
ladder  | 2023/11/08 11:08:36 Loaded rules for 3 Domains
ladder  |
ladder  |  ┌───────────────────────────────────────────────────┐
ladder  |  │                   Fiber v2.50.0                   │
ladder  |  │               http://127.0.0.1:8080               │
ladder  |  │       (bound on host 0.0.0.0 and port 8080)       │
ladder  |  │                                                   │
ladder  |  │ Handlers ............ 14  Processes ........... 1 │
ladder  |  │ Prefork ....... Disabled  PID ................. 7 │
ladder  |  └───────────────────────────────────────────────────┘
ladder  |
ladder  | 2023/11/08 11:08:44 GET /
ladder  | 2023/11/08 11:08:48 GET /https://test.de

Moved to new Github organization "everywall"

Hey everyone

I moved the ladder to its own Github organization, to avoid conflicts with my other side project Kubero.

Pulling docker images from the old organization is still possible. But you better use the new organization:

docker pull ghcr.io/everywall/ladder:latest 

I also opened the Discussions to have a more convenient method to address topics an general discussions.

Quick typo

I'm not going fork and PR just for a little typo, but in your README, it should be consider instead of concider

Feature: Browser extension

It would be great if there was a browser extension that could redirect sites to your locally running ladder instance!

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.