Giter Site home page Giter Site logo

tellerops / teller Goto Github PK

View Code? Open in Web Editor NEW
2.6K 29.0 179.0 10.67 MB

Cloud native secrets management for developers - never leave your command line for secrets.

Home Page: https://github.com/tellerops/teller

License: Apache License 2.0

PowerShell 0.87% Shell 0.95% Rust 98.00% JavaScript 0.12% Raku 0.06%
secrets secret-management vault hashicorp aws rust rust-lang

teller's Introduction






๐Ÿ’ป Never leave your terminal for secrets
๐Ÿ“Ÿ Create easy and clean workflows for working with cloud environments
๐Ÿ”Ž Scan for secrets and fight secret sprawl


Teller - the open-source universal secret manager for developers

Never leave your terminal to use secrets while developing, testing, and building your apps.

Instead of custom scripts, tokens in your .zshrc files, visible EXPORTs in your bash history, misplaced .env.production files and more around your workstation -- just use teller and connect it to any vault, key store, or cloud service you like (Teller support Hashicorp Vault, AWS Secrets Manager, Google Secret Manager, and many more).

You can use Teller to tidy your own environment or for your team as a process and best practice.

Quick Start with teller

Download a binary Grab a binary from releases

Build from source Using this method will allow you to eye-ball the source code, review it, and build a copy yourself.

This will install the binary locally on your machine:

$ cd teller-cli
$ cargo install --path .

Create a new configuration

$ teller new
? Select your secret providers โ€บ
โฌš hashicorp_consul
โฌš aws_secretsmanager
โฌš ssm
โฌš dotenv
โฌš hashicorp
โฌš google_secretmanager

Then, edit the newly created .teller.yml to set the maps and keys that you need for your providers.

A look at teller.yml

The teller YAML describes your providers and within each provider a map that describes:

  • What is the root path to fetch key-values from
  • For each such map, its unique id which will serve you for operations later
  • For each map, an optional specific key name mapping - you can rename keys that you will fetch from the source provider

Here's an example configuration file. Note that it also include templating constructs -- such as fetching environment variables while loading the configuration:

providers:
  hashi_1:
    kind: hashicorp
    maps:
      - id: test-load
        path: /{{ get_env(name="TEST_LOAD_1", default="test") }}/users/user1
        # if empty, map everything
        # == means map to same key name
        # otherwise key on left becomes right
        # in the future: key_transform: camelize, snake_case for automapping the keys
        keys:
          GITHUB_TOKEN: ==
          mg: FOO_BAR
  dot_1:
    kind: dotenv
    maps:
      - id: stg
        path: VAR_{{ get_env(name="STAGE", default="development") }}

You can now address these providers as hashi_1 or dot_1. Teller pulls the specified data from all providers by default.

Features

๐Ÿƒ Running subprocesses

Manually exporting and setting up environment variables for running a process with demo-like / production-like set up?

Got bitten by using .env.production and exposing it in the local project itself?

Using teller and a .teller.yml file that exposes nothing to the prying eyes, you can work fluently and seamlessly with zero risk, also no need for quotes:

$ teller run --reset --shell -- node index.js

๐Ÿ”Ž Inspecting variables

This will output the current variables teller picks up. Only first 2 letters will be shown from each, of course.

$ teller show

๐Ÿ“บ Local shell population

Hardcoding secrets into your shell scripts and dotfiles?

In some cases it makes sense to eval variables into your current shell. For example in your .zshrc it makes much more sense to use teller, and not hardcode all those into the .zshrc file itself.

In this case, this is what you should add:

eval "$(teller sh)"

๐Ÿณ Easy Docker environment

Tired of grabbing all kinds of variables, setting those up, and worried about these appearing in your shell history as well?

Use this one liner from now on:

$ docker run --rm -it --env-file <(teller env) alpine sh

โš ๏ธ Scan for secrets

Teller can help you fight secret sprawl and hard coded secrets, as well as be the best productivity tool for working with your vault.

It can also integrate into your CI and serve as a shift-left security tool for your DevSecOps pipeline.

Look for your vault-kept secrets in your code by running:

$ teller scan

You can run it as a linter in your CI like so:

run: teller scan --error-if-found

It will break your build if it finds something (returns exit code 1).

You can also export results as JSON with --json and scan binary files with -b.

โ™ป๏ธ Redact secrets from process outputs, logs, and files

You can use teller as a redaction tool across your infrastructure, and run processes while redacting their output as well as clean up logs and live tails of logs.

Pipe any process output, tail or logs into teller to redact those, live:

$ cat some.log | teller redact

It should also work with tail -f:

$ tail -f /var/log/apache.log | teller redact

Finally, if you've got some files you want to redact, you can do that too:

$ teller redact --in dirty.csv --out clean.csv

If you omit --in Teller will take stdin, and if you omit --out Teller will output to stdout.

๐Ÿ“œ Populate templates

You can populate custom templates:

$ teller template --in config-templ.t

Template format is Tera which is very similar to liquid or handlebars.

Here is an example template:

production_var: {{ key(name="PRINT_NAME")}}
production_mood: {{ key(name="PRINT_MOOD")}}

๐Ÿ”„ Copy/sync data between providers

In cases where you want to sync between providers, you can do that with teller copy.

Specific mapping key sync

You can use the <provider name>/<map id> format to copy a mapping from a provider to another provider:

$ teller copy --from source/dev --to target/prod,<...>

In this simplistic example, we use the following configuration file

providers:
  dot1:
    kind: dotenv
    maps:
      - id: one
        path: one.env
  dot2:
    kind: dotenv
    maps:
      - id: two
        path: two.env

This will:

  1. Grab all mapped values from source mapping
  2. For each target provider, find the matching mapping, and copy the values from source into it

By default copying will update target mapping (upsert data), if you want to replace you can use --replace.

๐Ÿšฒ Write and multi-write to providers

Teller providers supporting write use cases which allow writing values into providers.

Remember, for this feature it still revolves around definitions in your teller.yml file:

$ teller put --providers new --map-id one NEW_VAR=s33kret

In this example, this configuration is being used:

providers:
  new:
    kind: dotenv
    maps:
      - id: one
        path: new.env

A few notes:

  • Values are key-value pair in the format: key=value and you can specify multiple pairs at once
  • When you're specifying a literal sensitive value, make sure to use an ENV variable so that nothing sensitive is recorded in your history
  • The flag --providers lets you push to one or more providers at once

โŒ Delete and multi-delete from providers

Teller providers support deleting values from providers.

$ teller delete --providers new --map-id one DELETE_ME

A few notes:

  • You can specify multiple keys to delete, for example:
  • The flag --providers lets you push to one or more providers at once

YAML Export in YAML format

XXX TODO: rewrite how the command export works

You can export in a YAML format, suitable for GCloud:

$ teller export yaml

Example format:

FOO: "1"
KEY: VALUE

JSON Export in JSON format

You can export in a JSON format, suitable for piping through jq or other workflows:

$ teller export json

Example format:

{
  "FOO": "1"
}

Providers

You can get a list of the providers and their described configuration values in the documentation.

Testing check list:

  • docker on windows: if you have a container based test that uses Docker, make sure to exclude it on Windows using #[cfg(not(windows))]

  • resource semantics: while building providers, align with the semantics of empty and not found as two different semantics: if a provider supports an explicit "not found" semantic (404, NotFound, etc.), use Error::NotFound. Otherwise when a provider signals a "not found" semantic as an empty data bag, return an empty KV[] (i.e. do not translate a sematic of "empty" into "not found").

Testing

Testing is done with:

$ cargo test --all --all-features

And requires Docker (or equivalent) on your machine.

Thanks:

To all Contributors - you make this happen, thanks!

Code of conduct

Teller follows CNCF Code of Conduct

Copyright

Copyright (c) 2024 @jondot. See LICENSE for further details.

teller's People

Contributors

0xflotus avatar adamgoose avatar chengadev avatar cmpxchg16 avatar danielr18 avatar eladbash avatar guylev008 avatar idimov-keeper avatar infamousjoeg avatar itamarbareket avatar jacobjohansen avatar jeremylong avatar jkawamoto avatar jkirkpatrick24 avatar jondot avatar kaplanelad avatar kevbook avatar kpetremann avatar lreuven avatar magdyamr542 avatar mcalhoun avatar mkol5222 avatar mostafahussein avatar philippeckelintive avatar pkosiec avatar prochac avatar stvnksslr avatar tony-vsx avatar vongohren 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  avatar  avatar  avatar  avatar  avatar  avatar

teller's Issues

How would you suggest setting secrets?

Hi, this looks like an interesting project and our team is investigating whether it's a good fit for our workflow. We're wondering how you would suggest giving developers access to change secrets though, since this tool seems to only read from the secret stores. When using it, do you give developers direct access to the secret store to update values? Thanks!

Information request : Obfuscation functionality

Taking a look into docs, there is an secret obfuscation possibility

  1. Does it do secret obfuscation based on only known secrets?
  2. Can it be used for any data like history, where someone might accidentally paste a password or etc in clear text?
  3. teller --in dirty.csv --out clean.csv
    On MacOS

โžœ teller-test teller version Teller 1.0.0 Revision 684b421ad8f96acb3de9bcb0f75339d5b4912030, date: 2021-04-14T12:43:07Z โžœ teller-test teller --in file-t.txt --out clean.txt teller: error: unknown flag --in

gopass integration

It would be great if it would integrate with an existing gopass store

Ansible Vault

New Provider Request

Details

It would be great if Ansible Vault could be supported. That way it would be easy to re-use Ansible Vault secrets as environment variables. My example use case would be a setup where Ansible talks to an API and thus that API key is in Ansible Vault, and Terraform needs to talk to this API as well.

Securely identify person when interactive mode

In order to protect against unauthorized automation of Teller on a developer machine, we want interactivity to be protected with another layer -- configurable in teller.yaml.

Challenges:

  • It's recommended to have it by default ON, and only allow to suppress it via configuration (where people can do that in CI environments, where we assume people don't get physical access to). However changing this semantics is going to break a LOT of existing integrations. We need some smart backward-compat mode.

Implementation:

Lean version - touch ID only on mac:

Full version:

However, there probably is some ubikey/other methods of auth available such that a user can:

  1. Identify using their hard-access credentials, or OS credentials
  2. Or, by way of standard 2FA method (maybe through one of Google's own libs)

Thanks @eladbash for the idea

STDIN Shell Provider

Just came across this tool, super great. Been in devops for a few years and this definitely solves a need. Love the support for multiple providers within a single invocation.

I'm personally interested in gopass (#11) for some local only api keys. While I fully appreciate first class integration with providers, I'm wondering if #3 #10 #11 (and other future requests) could all be achieved if there was a generic shell provider. Using that provider would just invoke that shell script with a known STDIN api, ex [command] [path] [options].

What is the best way to manage environments?

I have not found any where I can set environment via cli flag, but I can use seperate files.
How are you using this today?
Or what is your best practise suggstion on this problem?

feat: Chaining / Extending / Merging config files

Hey there ๐Ÿ‘‹

I think it would be really excellent to support extending or merging teller config files. As we've begun to use teller more and more, we've found that often we need to have a teller config file for different environment. This would be similar to how chamber works with chaining services. The reason for this is sometimes in deployment context, our environment configuration will come from different providers.

An example of this would be a DATABASE_URL. If I am deploying my application on heroku, and using their database extensions, this variable will be accessible from the heroku provider, and thats where the app should consume it from. In other deployment/development contexts, I would want to access this variable from another provider. (e.g the AWS SSM param store).

For a situation like this, I end up with config files that look like this:

project: hello-world-production
providers:
  aws_ssm:
    env:
      SECRET_KEY:
        path: /{{project}}/{{environment}}/secret_key
        decrypt: true
  heroku:
    env:
      DATABASE_URL:
        path: hello-world-{{environment}}

and:

project: hello-world-production
providers:
  aws_ssm:
    env:
      SECRET_KEY:
        path: /{{project}}/{{environment}}/secret_key
        decrypt: true
      DATABASE_URL:
        path: /{{project}}/{{environment}}/database_url
        decrypt: true

The problem with this is the duplication of env declarations across files. I need to define SECRET_KEY in both files. It would be amazing we could avoid this duplication by merging configs in some way. An example of this could look like

Core configuration shared across environments:

// .teller.yml
project: hello-world-production
providers:
  aws_ssm:
    env:
      SECRET_KEY:
        path: /{{project}}/{{environment}}/secret_key
        decrypt: true

and production specific file:

// .teller.deploy.yml
providers:
  heroku:
    env:
      DATABASE_URL:
        path: /{{project}}/{{environment}}/database_url
        decrypt: true

Run teller:

teller run -c .teller.yml -c .teller.deploy.yml -- my command

This would merge the above files and inject both the SECRET_KEY and DATABASE_URL environment variables.

Hopefully that explains the issue well! Happy to answer any questions about this! Thanks.

Ability to delete secrets

Hello again,

Teller already supports:

  • Put (as create+update; both for single and multiple values)
  • Get (get/list) for the providers
  • copying (syncing) all secrets from one provider to another one

Did you also think about supporting Delete? It could be a simple teller delete command. What I'm thinking is extending the Provider interface:

type Provider interface {
	// (...)

        Delete(p KeyPath) error
        DeleteMapping(p KeyPath) // probably this would be also useful
}

In a result, Teller would support the full lifecycle of secret management, which could be extremely useful.

We at Capact would be very interested in this feature ๐Ÿ™‚ And, we would love to contribute - Initially, in next few days, I could prepare such Delete functionality for dotenv and AWS Secrets Manager providers. At some point, we would also need full lifecycle support for Vault, which means we can also take care of the implementation ๐Ÿ™‚

Cheers!

Adding Application Logger

We need to add an application logger into our code for:

Why?

  1. Better debugging visibility
  2. Gives the user more verbosity on the commands
  3. Allow to attache log when users open an issue

How:

Implement logger and cover the essential places with the log message

Note

We need to keep the STDOUT cleanest like we have today. The log will throw to the screen only in errors or when the user asks for with new flag --log-level to any Teller commands.

Brew install teller fails

in https://tlr.dev/#install it says to install teller like brew install teller but that fails

โฏ brew install teller
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> Updated Formulae
Updated 9 formulae.
==> Updated Casks
Updated 2 casks.

==> Searching for similarly named formulae...
Error: No similarly named formulae found.
Error: No available formula or cask with the name "teller".
==> Searching for a previously deleted formula (in the last month)...
Error: No previously deleted formula found.
==> Searching taps on GitHub...
Error: No formulae found in taps.

I guess you meant brew install spectralops/tap/teller or brew tap spectralops/tap && brew install teller like in the readme file.

โœจ FR: Multiple projects in one

Use case, if you have a frontend and a backend project and the frontend one has the backend url/port as env var and the backend has an env var vor its port also both would need a teller file and the teller file needs to be in the project folder.
Instead, an option for having a central teller file for multiple possibly overlapping project that don't have to be checked in at all and can reside in the home directory would be nice.

OT: Teller Meaning

Not to water your wine
This is a 'Teller' in Germany ๐Ÿฝ๏ธ
image

Question: hashicorp vault auth

Hi. I've recently discovered your project and fascinated with capabilities it provides. However, there is some things that are not completely clear for me. As you might guessed from a title, I am figuring out how does Teller authenticates against Hashicorp Vault.
Readme says:

if for example you connect to your organization's Hashicorp Vault, we assume you already have a secure way to do that, which is "blessed" by the organization.

Does this mean that Teller inherits all auth methods Vault provides, or it is up to me how to acquire and feed Teller with VAULT_TOKEN? I am specifically interested in AWS Auth method, since Teller might perfectly fit to my ECS runtime as secret injection tool.

build a docs website w/docusaurus

Time for shaping the content. Build a docs website based on the following TOC:

  • Quickstart
  • Providers (let's also do something smart. Each provider should also specify declaratively what it supports, so when we run something like "teller providers --info" we get a JSON that we can bake into the docs). In other words - we want the providers to be self-documenting so that:
  1. maintainers can contribute very easily
  2. syncing the docs provider section is effortless or automatic
  • Usage (list all use cases)
  • FAQ
  • Design principles
  • Contributing (developer's guide)

Question: How exactly do I use?

Hello, I stumbled upon this project while looking for a way to sync my secrets from AWS Secrets Manager to my application server. Originally we are using dotenv (.env) with nodejs to set the secrets for the app. We're looking to move to AWS Secrets Manger to host the secrets and then import them into the application server into a dotenv file. How can I achieve this with teller?

Cloudflare worker secrets Write-only Providers support

Hello ๐Ÿ‘‹ !

I was having a look though the teller roadmap and see that there are plans for adding "write only" provider support. I think this is an excellent Idea and would be something would be really useful. In particular for our team, adding support for cloudflare workers secrets would be extremely useful for our workflows. I would be happy to contribute a PR for this.

Has there been any work put into designing/implementing this feature yet?

Cheers

Possibility for defaults and not required in the config file

Default value for opts

I use this alot

  opts:
  #region: env:AWS_REGION    # you can get env variables with the 'env:' prefix
  prefix: env:PREFIX

But it would be great with a way to say that something was default?

dotenv not required

I also use this alot

dotenv:
    env_sync:
      path: ./.env.local

It would be great to have an option to mark this as not required meaning that it does not crash when there is not file found. Because this particular example is only used for local override of config

Teller run as documented not passing flags to child process

The teller run function as documented does not pass flags to the child process. The following should return help for psql instead of printing help for teller:

# teller run psql --help                               
Usage: teller run <cmd> ...

Run a command

Arguments:
  <cmd> ...    Command to execute

Flags:
  -h, --help             Show context-sensitive help.
  -c, --config=STRING    Path to teller.yml

The work around is to use -- between run and the child process to exec.

teller run -- your-process arg1 arg2... --switch1 ...

This is expected behavior as referenced in alecthomas/kong#80

Add docker secret files support

New Provider Request

Details

For security reasons secrets should be mounted as files inside docker container rather than passed as environment variable. However only few applications support those files. For easy solving this issue it would be great to have a tool which transforms secrets from files into environment variables, but inside the container.

When doing `Put` for dotenv provider, an error is returned if a target file doesn't exist

Hi,

Very cool project! I would be interested to use it as Go API for accessing different secret storage backends (Delegated storage feature for https://github.com/capactio/capact open source project), as you prepared great abstractions.

Anyway, while playing around with Teller Go API, I noticed the following behavior for dotenv Provider. When doing Put, it returns an error when a given file doesn't exist.

I would love to prepare a pull request to fix such issue for dotenv provider. In fact, I have the code ready, but I want to confirm first the expected behavior.

Expected behavior

I would expect that the Put method is doing upsert (create or update) operation, like PUT in REST API. By reading the code, this is how I believe the vault, heroku and etcd providers work.

Minimal example to reproduce

package main

import (
	tellerpkg "github.com/spectralops/teller/pkg"
	"github.com/spectralops/teller/pkg/core"
	"log"
)

func main() {
	providers := tellerpkg.BuiltinProviders{}
	provider, err := providers.GetProvider("dotenv")
	if err != nil {
		panic(err)
	}

	key := core.KeyPath{
		Path:  "/tmp/foo.env",
		Field: "data",
	}

	val := `{"key": "true"}`
	err = provider.Put(key, val)
	if err != nil {
		panic(err) // it will panic here
	}

	// Get
	entry, err := provider.Get(key)
	if err != nil {
		panic(err)
	}

	log.Printf("%+v\n", entry)
}

Result:

panic: open /tmp/foo.env: no such file or directory

Support hashicorp vault database secrets engine

I think teller may be able to help a use case that I have in fetching hashicorp vault dynamic database secrets. The dynamic database secrets engine creates and returns a username and password for databases. This is useful for security reasons but can be cumbersome when using database clients such as psql or mysql.

I think teller might be helpful by fetching the dynamic username and password from vault, setting the correct environment variables, and runing the database client. However, the data structure returned by vault is slightly different than the kv data structure.

The vault kv data structure containing secrets returns a double data.data{} object. Whereas the vault database secrets engine returns data{}.

If teller supported the database endpoint the following .teller.yml could be used to set the correct environment variables and connect to postgres:

project: postgres_client
providers:
  hashicorp_vault:
    env:
      PGUSER:
        path: database/creds/my-role
        field: username
      PGPASSWORD:
        path: database/creds/my-role
        field: password

Then, one could connect to the database using psql:

teller run psql -h db.example.com -d postgres

I think support could be added to teller by adjusting the double data.data{} assumptions in hashicorp_vault.go#L60 and hashicorp_vault.go#L84.

Any thoughts on this? I can open a PR if their is interest.

Can't access Vault secrets

I'll preface this by saying I'm pretty new to Vault in general, and odds are I'm just doing something incorrectly. For some reason Teller is unable to read from my Vault cluster. I've done several different combinations of secret locations to try and get it to read, for example:

  • secret/data/{{stage}}/test/teller
  • secret/data/{{stage}}/test
  • secrets/{{stage}}/test/teller
  • secrets/{{stage}}/test
  • {{stage}}/test/teller
  • {{stage}}/test

Regardless of what I use I get back the error that data not found at <insert_vault_string>. However, I am able to read it just fine by running the vault kv get developement/test/teller directive. Any insight into what I may be doing wrong here?

Teller Config:

project: teller-test
confirm: Are you sure you want to run on {{stage}}?
opts:
  region: env:AWS_REGION
  stage: development
providers:
  hashicorp_vault:
    env_sync:
      path: 'secret/data/{{stage}}/test/teller'
    env:
      TELLER_TEST_SECRET:
        path: '{{stage}}/test'
        field: teller

Screenshot of Vault store:

image

Screenshot of terminal call:

image

Providers should be self documenting: design

Spec out a design suggestion for self-documenting providers.

Each provider should have a metadata part, where it will declare:

  • name (already exists today)
  • description
  • support matrix (read/write,etc.)
  • example usage / use case
  • 'more info' (regarding the provider)

Notes:

  • Implement this as serializable so it would be easy to dump from a running process
  • Developer experience should be as effortless as possible, so explore Golang codegen if necessary, or, try to interpolate the support matrix from actual implementation (can we reflect/observe current implementations?)

support mac M1 for brew tap

Using M1 mac

โœฆ โฏ brew tap spectralops/tap
==> Tapping spectralops/tap
Cloning into '/opt/homebrew/Library/Taps/spectralops/homebrew-tap'...
remote: Enumerating objects: 53, done.
remote: Counting objects: 100% (53/53), done.
remote: Compressing objects: 100% (47/47), done.
remote: Total 53 (delta 24), reused 12 (delta 1), pack-reused 0
Receiving objects: 100% (53/53), 9.23 KiB | 1.84 MiB/s, done.
Resolving deltas: 100% (24/24), done.
Error: Invalid formula: /opt/homebrew/Library/Taps/spectralops/homebrew-tap/netz.rb
formulae require at least a URL
Error: Invalid formula: /opt/homebrew/Library/Taps/spectralops/homebrew-tap/senv.rb
formulae require at least a URL
Error: Cannot tap spectralops/tap: invalid syntax in tap!

Teller env output multiple formats

Hi guys! I really like this tool, I just have one concern and that is that it would be great with multiple formats for teller env
Some flag to be able to set what shall be outputed.

F.ex, google cloud functions have a way to set envs via file, but they expect a yml file.
You can set via an array, but again, this format only outputs as an .env file.

Has there been any thoughts around this or exist some undocumented code?

Some documentation, search for --env-vars-file in https://cloud.google.com/sdk/gcloud/reference/functions/deploy

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.