Git Product home page Git Product logo

nix-expressions's Introduction

1. Syslab Nix Expressions

This project contains nix expressions for the syslab courses at HTWG Konstanz. The expression are written in the nix language for the package manager with the same name.

This README aims to be a mixture of

  • nix tutorial
  • presentation for the design decisions
  • labshell installation usage documentation

1.1. Overview

1.2. Requirements

In order to make use of this project you need to have nix and its many utilities installed locally. After the installation you should have these tools in your PATH:

  • nix-prefetch-url - Used to download and store files in the nix store
  • nix-instantiate - instantiates expressions to derivations
  • nix-build - Build derivations without installing them to the environment
  • nix-env - Evaluates expressions to derivations and installs these into your current shell environment You can test this with

    nix-env -i hello (will work only as root on the HTWG Syslab Containers for now)

  • nix-shell - launches a new shell environment based on the derivations built by nix-instantiate

1.3. Repository Overview

The following is a simplified tree layout for the files in this repository and their purpose:

.
├── default.nix (the nix entry point, exposes packages and shell flavors)
├── README.md (this file)
├── ci (scripts for integration tests)
│   ├── complete.sh
│   ├── install.sh
│   ├── source.sh
│   └── test.sh
├── pkgs (package definitions)
│   ├── configured
│   │   └── (...)
│   ├── labshell (the package provides the wrapper scripts)
│   │   ├── default.nix
│   │   └── src
│   │       └── labshell.sh (the script that executes nix-shell)
│   └── overrides
│       └── default.nix (some nix configuration overrides)
└── shells
    ├── default.nix (the definitions for the shell flavors)
    └── mkShellDerivation.nix (the function used to build shell flavors)

1.4. Usage and Design

The main components are the nix expressions themselves, and the labshell.sh script source code. The latter has an installable nix package in this repository.

1.4.1. The labshell derivation

The labshell derivation that is written in pkgs/labshell/default.nix allows to install a shell script that wraps the execution of pkgs/labshell/src/labshell.sh. It is used to set default values for environment variable that alter the runtime behavior of labshell.sh.

To understand how this project works, it is very useful to read the nix manual section about writing nix expressions along with this README. Especially important is to understand how mkDerivation works to build an installable package, and how the installation procedure can be adjusted. If in doubt, contact the IRC channel #nixos at FreeNode and feel free to ping steveeJ.

The output path of the derivation contains only one binary:

/nix/store/<HASH>-labshell/
└── bin
    └── labshell

On a local build this file looks like this, built from a local copy of the repository with nix-build -A labshell --arg labshellExpressionsUpdateFromLocal true

#! /nix/store/53h800j8kgpj0a349f7wxa5hgkj1vby2-bash-4.4-p12/bin/bash -e
export LABSHELL_EXPRESSIONS_LOCAL="${LABSHELL_EXPRESSION_LOCAL:-/home/steveej/src/htwg-syslab/nix-expressions}"
export LABSHELL_EXPRESSIONS_REMOTE_URL="${LABSHELL_EXPRESSIONS_REMOTE_URL:-/home/steveej/src/htwg-syslab/nix-expressions}"
exec "/home/steveej/src/htwg-syslab/nix-expressions/pkgs/labshell/src/labshell.sh"  "${extraFlagsArray[@]}" "$@"

This wrapper is generated in the installation step of the labshell nix derivation.

When the wrapper is run, a new shell is spawned and PATH and other environment variables are altered so that no utilities from the host are accessible. This is done by using nix-shell's --pure argument.

1.4.2. Update Handling

Updates only take place if LABSHELL_UPDATE is not 0.

In the above example the URL for updates is a local directory, which is very practical for development. On production installations this URL will download the archive from a online repository.

1.4.3. The script pkgs/labshell/src/labshell.sh

This is where the hard work is done to figure out which of nix-* tools needs to be invoked at which time. The main job of the script is to set up the invocation parameters for the nix-shell with the shell flavor that can be passed to, as described in the usage section.

This section gives an idea of the supported features.

1.4.4. Logical modes and choice of the shell flavor

The labshell application currently supports two logical modes: interactive and shell. These modes are not explicitly specified but inferred from the way the labshell script is invoked.

1.4.4.1. 'Interactive' Mode

This mode is to launch a shell in which the user works interactively.

1.4.4.1.1. Zero arguments passed

If labshell is run without any arguments it will use the base flavor and start an interactive shell with it.

1.4.4.1.2. One Argument passed

In case there is exactly one arguments passed, it will be interpreted as the flavor.

labshell FLAVOR

1.4.4.2. Shell mode

In 'shell' mode, the invocation of the script behaves the same as invoking bash, just that the shell is run with the environment defined by LABSHELL_FLAVOR.

In this mode, labshell behaves like a shell which allows it to be placed in the SHELL environment variable. In fact, if you spawn a labshell you will see something like this:

steveej@steveej-laptop ✓ »base@2« ~/src/htwg-syslab/nix-expressions
$ echo $SHELL
/nix/store/5zc5ljyp55k0533fp4z46kx7x02pyz2s-labshell_base/bin/labshell_base

This variable is used by many utilities like tmux or vim, which enables them to access the tools that are defined in the shell environments.

1.4.4.2.1. Passed via environment variable LABSHELL_FLAVOR

In this case, the invocation looks like this

[LABSHELL_FLAVOR=flavor...] labshell [ARGUMENTS PASSED TO BASH ...]`

1.4.4.2.2. Invocation as #! (sharp-bang) Interpreter

The labshell script is designed to be used as a script interpreter, which enables the users to write scripts that can be invoked in batch jobs.

The generic syntax of a shell script looks like this:

#/usr/bin/env labshell
#!LABSHELL_OPTION1=VALUE1
#!LABSHELL_OPTION2=VALUE2
#!  (...)
#!/path/to/real/interpreter argument
commands for the real interpreter
(...)

Valid LABSHELL_OPTIONS are currently:

  • LABSHELL_FLAVOR=flavor - has the same effect as setting the LABSHELL_FLAVOR=flavor environment variable, or arg1 in the interactive mode

It is best to prepend /usr/bin/env instead of using an unreliable hardcoded path.

#!/usr/bin/env labshell
#!LABSHELL_FLAVOR=code
#!/bin/sh -xe
echo I'm verbose and running with the ${LABSHELL_FLAVOR} flavor.

1.4.4.3. The mkShellDerivation(.nix) function

This nix expression represents a function that emits an installable derivation, that can also be used to instantiate a nix-shell environment.

Some of the cornerstones of this derivation:

  • The list of packages declared by the buildInputs attribute of packages will be available in the environment, which is called a flavor within the context of this project.

  • The shellHook string are bash commands that are run just before the shell is spawned.

    It can be used to set environment variables or perform other initialization tasks.

1.4.5. Shell derivations (shells/default.nix) - Labshell flavors

The flavors effectively define an environment construct that consists a list of packages (-> buildInputs) and a string (-> shellHooks)

The dependencies and strings are organized by use-case and laboratory requirements. The file should be self explanatory but roughly the following is true:

  • all flavors are built with mkShellDerivation
  • base and code collections for generic tasks and text editing (does not include language specific code completion tools)
  • admin tools
  • every programming language has it's own package collection for tools and compilers
  • every course has its own shell derivation

The flavors that are ultimately available for installation are exposed in the default.nix file by inheriting these from shells/default.nix, which was just discussed.

(...)
  inherit ( callPackage ./shells { } )
    shell_base
    shell_admin
    (...)
    ;
(...)
;

1.5. Installation

1.5.1. The labshell application

  1. Install labshell Package from the Repository on the target machine.

    REV=sj-improve-labshell-script \
        nix-env -iA labshell \
        --argstr labshellExpressionsRemoteRev ${REV} \
        -f https://github.com/htwg-syslab/nix-expressions/archive/${REV}.tar.gz

    nix-env will download and unpack the tar archive and automatically read its default.nix file, and start evaluating the expression pkgs.labshell, which is a derivation that installs a labshell wrapper script in the current PATH. The example uses a development branch.

    For the HTWG Syslab Container infrastructure, this is accomplished via ansible-playbook (convenience link, requires permission)

  2. On the target machine you can now see that labshell is installed. In fact, the script in PATH is a wrapper to the labshell wrapper :-)

    $ type labshell
    labshell is /home/sjunker/.nix-profile/bin/labshell
    $ cat $(type -P labshell)
    #! /nix/store/hi4j75r312lsjhpdln9p8blyixs59hbs-bash-4.4-p12/bin/bash -e
    exec "/nix/store/28pbgmrly69j0yvjxmrgighva0nl5jd3-sj-improve-labshell-script.tar.gz/pkgs/labshell/src/labshell.sh"  "${extraFlagsArray[@]}" "$@"

    This wrapper will probably be extexnded with default environment variables.

1.5.2. The labshell_${flavor} wrappers

The installation is analogue to the labshell wrapper script. The following example uses a local repository for bootstrapping.

steveej@steveej-laptop ✗ ~/src/htwg-syslab/nix-expressions
$ nix-env -iA shell_base -f .
replacing old ‘shell_base’
installing ‘shell_base’
these derivations will be built:
  /nix/store/7j538si1ggq90c1vzpdz9pf7ivicmwyv-shell_base.drv
building path(s) ‘/nix/store/37fa5qrpbrqy9p905kd48bd299wyk0d4-shell_base’
installing
building path(s) ‘/nix/store/m02ly71nmxxhcinkmds9ij6xlylgpx6v-user-environment’
created 1749 symlinks in user environment
steveej@steveej-laptop ✓ ~/src/htwg-syslab/nix-expressions
$ cat $(type -P labshell_base)
#! /nix/store/hi4j75r312lsjhpdln9p8blyixs59hbs-bash-4.4-p12/bin/bash -e
export LABSHELL_EXPRESSIONS_LOCAL="/home/steveej/src/htwg-syslab/nix-expressions"
export LABSHELL_EXPRESSIONS_REMOTE_URL="https://github.com/htwg-syslab/nix-expressions/archive/master.tar.gz"
export LABSHELL_MODE="shell"
export LABSHELL_UPDATE="0"
export LABSHELL_FLAVOR="base"
unset LABSHELL_EXPRESSIONS_REMOTE_URL
exec "/home/steveej/src/htwg-syslab/nix-expressions/pkgs/labshell/src/labshell.sh"  "${extraFlagsArray[@]}" "$@"

1.6. Development

For development the repository needs to be cloned locally.

1.6.1. Clone Repository

$ git clone [email protected]:htwg-syslab/nix-expressions.git
$ pushd nix-expressions

1.6.2. Test changes to a shell derivation

The following example assumes $PWD is the path of the git repository.

  1. Make your desired changes E.g., change the shell derivations and its dependencies:

    $EDITOR shells/default.nix

    Read the comments in the file :-) If you add a new shell, you also need to add the derivation name in the default.nix in the repository root.

  2. Try out your changes locally

    1. Use a local build of the labshell wrapper:
      steveej@steveej-laptop ✓ ~/src/htwg-syslab/nix-expressions
      $ nix-build -A labshell --arg labshellExpressionsUpdateFromLocal true
      /nix/store/a8893zppmlb75lmir7czfr3mkb2r0qla-labshell
      steveej@steveej-laptop ✓ ~/src/htwg-syslab/nix-expressions
      $ ./result/bin/labshell
      Spawning shell with settings:
          flavor: 'base'
          #!-Interpreter: 0
      Please wait...
      Using expressions on filesystem /home/steveej/src/htwg-syslab/nix-expressions
      Environment initialized!
      steveej@steveej-laptop ✓ »base@2« ~/src/htwg-syslab/nix-expressions
      $
    2. Use result/bin/labshell to test changes to the local repository

1.6.3. Tests

  • If nix-env --install ... works for you, simply run: ./ci/complete.sh
  • Document how to run it with nix-build result.

1.6.4. Contribution Policy

The master branch is protected, hence all changes must go through Pull-Requests which require status checks.

nix-expressions's People

Contributors

steveej avatar mmaechtel avatar sww13 avatar sjunker-htwg avatar

Watchers

James Cloos avatar Johannes Waidner avatar  avatar

nix-expressions's Issues

gdb is missing

in which part of the nix shell calling hierarchy should we integrate gdb. gdb is needed in rust as well so maybe developer ... or basic?

shell_base: missing redirections

syntastic: error: your shell /nix/store/2vfxa3sg3zl5l9qbvzcyc48hahv8y75a-nixshwrap/bin/nixshwrap can't handle traditional UNIX syntax for redirections
Press ENTER or type command to continue

ssh reports unsupported options

when doing a git push, ssh reports:

/etc/ssh/ssh_config line 53: Unsupported option "gssapiauthentication"
/etc/ssh/ssh_config line 54: Unsupported option "gssapidelegatecredentials"

the git push works, just the above additional output ...

rustfmt 0.7 VS recent rustfmt 0.83

rustfmt on workstation ist quite 'old' .... the recent rustfmt version is 0.83 (on my system)

The results from running these different versions produce different output.

So, I think we need a fast update solution, otherwise we have problems running the ci tests on different systems. Of course I could downgrade, but this only delays the next update problems.

Error when executing new shell flavour as shell

Executing new shell flavour in interactive labshell as shell results in regex error.

test.sh:

#!/usr/bin/env labshell
#!LABSHELL_FLAVOR=sysoHW1
#!/bin/sh -xe
echo "$@"

How to reproduce:

# new environment - no labshell used so far

# first time new shell flavor is executed as shell -> error
$ labshell sysoHW2
»sysoHW2@1 $ ./test
# ++ nix-instantiate -A shell_sysoHW1 /nix/store/3l8yllqvd3815k2p4l7k48012wlv892z-sj-improve-labshell-script.tar.gz
# error: regex_error

# use shell flavor
»sysoHW2@1 $ ^D
$ labshell sysoHW1
# ++ nix-instantiate -A shell_sysoHW1 --argstr LABSHELL_EXPRESSIONS_REMOTE_URL /nix/store/3l8yllqvd3815k2p4l7k48012wlv892z-sj-improve-labshell-script.tar.gz /nix/store/3l8yllqvd3815k2p4l7k48012wlv892z-sj-improve-labshell-script.tar.gz
»sysoHW1@1 $ ^D

# second time -> works
$ labshell sysoHW2
»sysoHW1@1 $ ./test
# -> works

ssh-agent connection error

shell: bsys

$ ssh-agent
SSH_AUTH_SOCK=/tmp/1003/ssh-dhl89GrpQMub/agent.23291; export SSH_AUTH_SOCK;
SSH_AGENT_PID=23292; export SSH_AGENT_PID;
echo Agent pid 23292;

$ pgrep ssh-agent
23292

$ ssh-add -t 1h
Could not open a connection to your authentication agent.

travis: exceeding of time-limit

We constantly fail the tests because the time limit of 50 minutes is exceeded. Until we have a better way to cache derivations between runs there is no way around these long runtimes.

I will reside to running the tests locally for the time being.

shell/?: gdb error

(gdb) list
1 int main(int argc, char const *argv[])
2 {
3 int *x = 0;
4 int y = *x + 1;
5 return 0;
6 }
(gdb) b 3
Breakpoint 1 at 0x400540: file null.c, line 3.
(gdb) run
Starting program: /home/maechtel/tmp/null
/nix/store/pbs5sfnp9bfv27vz9m7h64w3zgkavfqd-perl-5.22.2/bin/perl: symbol lookup error: /nix/store/pbs5sfnp9bfv27vz9m7h64w3zgkavfqd-perl-5.22.2/bin/perl: undefined symbol: rm
[Inferior 1 (process 2263) exited with code 0177]
(gdb)

sublime syntax check with cargo fails

Sublime rust-enhanced plugin: When saving a file, cargo does not run and the syntax is not checked. Output of Menu:Show Console

Running 'cargo metadata --no-deps'
Failed to run: cargo metadata --no-deps

Normal builds (CTRL-SHIFT-B) work, than cargo is found ....

shells: broken nightly prevents labshell from spawning

Since #91 all shells that use rust also use nightly for the rls binary. Unfortunately nightly brakes sometimes, and then the shell won't spawn at all:

sjunker@ct-staff-0 ✓ ~
$ labshell bsys
Spawning shell with settings:
    flavor: 'bsys'
    #!-Interpreter: 0
Please wait...
Downloading expressions from https://github.com/htwg-syslab/nix-expressions/archive/master.tar.gz
these derivations will be built:
  /nix/store/ad89fb15hpyz0i9qjjqjhi7njf58qd1n-labshell_bsys.drv
  /nix/store/b0j0lqxlvsxn50zk217f5rlnmrwgd814-rust-1.19.0-nightly-2017-05-18-0ed1ec9f9.drv
  /nix/store/xsywd4gvfwp8hxn4crbybhq7rqsb0lci-labshell_bsys.drv
  /nix/store/pwz8b6in5ram8dbrq046ihqm9d9p585k-rcFile.drv
building path(s) ‘/nix/store/arnfwgga7z4hsx7irz9xwa9jxws58zb0-labshell_bsys’
building path(s) ‘/nix/store/2k1fbp90advnfhzfpg620rq1wisq4qg0-labshell_bsys’
building path(s) ‘/nix/store/4ygkmmr83sz4n3gm3g1fxg4fwpdpkdvx-rust-1.19.0-nightly-2017-05-18-0ed1ec9f9’
builder for ‘/nix/store/b0j0lqxlvsxn50zk217f5rlnmrwgd814-rust-1.19.0-nightly-2017-05-18-0ed1ec9f9.drv’ failed with exit code 1
error: build of ‘/nix/store/b0j0lqxlvsxn50zk217f5rlnmrwgd814-rust-1.19.0-nightly-2017-05-18-0ed1ec9f9.drv’ failed
/home/sjunker/.nix-profile/bin/nix-shell: failed to build all dependencies

Mergetool please

Is it possible to get a mergetool to make merging the branches more simple?

Update rustfmt in container

@steveej

Since version 0.9, rustfmt uses the RFC style as default. Is an update in the containers possible 'today' ?, since the lab starts today with tasks, where we use rustfmt.

admin.nix

above all others rules the admin.nix !

labshell/SHELL: should point to script that uses cached derivations created with nix-instantiate

It could look something like this

steveej@steveej-laptop ✓ ~/src/htwg-job/htwg-syslab/nix-expressions
$ nix-instantiate --argstr shDrv $PWD -A shell_code .
warning: you did not specify ‘--add-root’; the result might be removed by the garbage collector
/nix/store/wadwjkvbl6r4xg6idv1fxi48kj9d31xr-shell_code.drv
steveej@steveej-laptop ✓ ~/src/htwg-job/htwg-syslab/nix-expressions
$ nix-shell /nix/store/wadwjkvbl6r4xg6idv1fxi48kj9d31xr-shell_code.drv
steveej@steveej-laptop ✓ »shell_code@3« ~/src/htwg-job/htwg-syslab/nix-expressions
$ 

missing shell for syso

Packages

  • git
  • strace
  • curl/wget
  • qemu-system for x86_64 and equivalent of RPI3
  • compiler for x86_64
  • cross compiler for x86_64 -> rpi 3 equivalent ARM

sysoHW*: rust missing crosscompile target

⇒  cargo build --target=aarch64-unknown-linux-gnu
   Compiling mynull-test v0.1.0 (file:///[...]/mynull-test)
error[E0463]: can't find crate for `std`
  |
  = note: the `aarch64-unknown-linux-gnu` target may not be installed

shells/rust: cargo requires ssl certificates from the host

    Updating registry `https://github.com/rust-lang/crates.io-index`
error: failed to fetch `https://github.com/rust-lang/crates.io-index`

Caused by:
  [16/-17] The SSL certificate is invalid

cargo searches for ca cert bundle in some default paths, see:
https://github.com/alexcrichton/openssl-probe/blob/master/src/lib.rs#L17-L27
https://github.com/alexcrichton/openssl-probe/blob/master/src/lib.rs#L62-L66

The list above may differ for current version of cargo:

stat("/var/ssl", 0x7fff31ace080)        = -1 ENOENT (No such file or directory)
stat("/usr/share/ssl", 0x7fff31ace080)  = -1 ENOENT (No such file or directory)
stat("/usr/local/ssl", 0x7fff31ace080)  = -1 ENOENT (No such file or directory)
stat("/usr/local/openssl", 0x7fff31ace080) = -1 ENOENT (No such file or directory)
stat("/usr/local/share", {st_mode=S_IFDIR|0755, st_size=40, ...}) = 0
stat("/usr/lib/ssl", 0x7fff31ace080)    = -1 ENOENT (No such file or directory)
stat("/usr/ssl", 0x7fff31ace080)        = -1 ENOENT (No such file or directory)
stat("/etc/openssl", 0x7fff31ace080)    = -1 ENOENT (No such file or directory)
stat("/etc/pki/tls", 0x7fff31ace080)    = -1 ENOENT (No such file or directory)
stat("/etc/ssl", {st_mode=S_IFDIR|0555, st_size=60, ...}) = 0
stat("/usr/local/share/cert.pem", 0x7fff31ace140) = -1 ENOENT (No such file or directory)
stat("/usr/local/share/certs.pem", 0x7fff31ace140) = -1 ENOENT (No such file or directory)
stat("/usr/local/share/certs/ca-certificates.crt", 0x7fff31ace140) = -1 ENOENT (No such file or directory)
stat("/usr/local/share/certs/ca-root-nss.crt", 0x7fff31ace140) = -1 ENOENT (No such file or directory)
stat("/usr/local/share/certs", 0x7fff31ace140) = -1 ENOENT (No such file or directory)
stat("/etc/ssl/cert.pem", 0x7fff31ace140) = -1 ENOENT (No such file or directory)
stat("/etc/ssl/certs.pem", 0x7fff31ace140) = -1 ENOENT (No such file or directory)
stat("/etc/ssl/certs/ca-certificates.crt", 0x7fff31ace140) = -1 ENOENT (No such file or directory)
stat("/etc/ssl/certs/ca-root-nss.crt", 0x7fff31ace140) = -1 ENOENT (No such file or directory)
stat("/etc/ssl/certs", {st_mode=S_IFDIR|0555, st_size=60, ...}) = 0

shell_bsys: sublime3 has locale issues

sublime3 throws the following error within shell_bsys

Package Control

Your system's locale is set to a value that can not handle non-ASCII characters. Package Control can not properly work unless this is fixed.

On Linux, please reference your distribution's docs for information on properly setting the LANG and LC_CTYPE environmental variables. As a temporary work-around, you can launch Sublime Text from the terminal with:

LANG=en_US.UTF-8 LC_CTYPE=en_US.UTF-8 sublime_text

Closes #9

shells/sysoHW3: binaries for aarch64 are in PATH

$ which clear
/nix/store/bhyp2vkkzkhd0310n7wf918b1fxv10ml-ncurses-6.0-aarch64-linux-gnu/bin/clear
fagendus@ct-syso-ss17-7 ✓ »sysoHW3@2« ~/SYSO/syso-ss17-grp7/HW3
$ clear
bash: /nix/store/bhyp2vkkzkhd0310n7wf918b1fxv10ml-ncurses-6.0-aarch64-linux-gnu/bin/clear: cannot execute binary file: Exec format error

/cc @fabs77

gcc undefined behavior different nix nix-shell env

Normally this programm segfaults:

int main(int argc, char const *argv[])
{
    int *x = 0;
    int y = *x + 1;
    return 0;
}

but not compiled with the gcc version installed via nix-shell. How does the gcc differ in nix-shell env to other linux env? For bsys I need the old 'segfault' behavior back ... also I need a working gdb see #46

HOWTO Using nix-shell in bsys

  • which workstation is for tests?
  • who needs access to this workstation?
  • small docu about how to use nix-shell environment in bsys.
  • do we need a github-test-grp?

travis: can't nest labshells because it doesn't run nix-daemon

++ nix-prefetch-url --unpack --print-path https://github.com/htwg-syslab/nix-expressions/archive/sj-improve-labshell-script.tar.gz
unpacking...
error: couldn't change to directory of ‘/nix/var/nix/daemon-socket/socket’: No such file or directory

shells_*: nix-shells have POSIX locale

It should be like:

LANG=C
LANGUAGE=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
LC_NUMERIC=de_DE.UTF-8
LC_TIME=de_DE.UTF-8
LC_COLLATE=de_DE.UTF-8
LC_MONETARY=de_DE.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_PAPER=de_DE.UTF-8
LC_NAME=de_DE.UTF-8
LC_ADDRESS=de_DE.UTF-8
LC_TELEPHONE=de_DE.UTF-8
LC_MEASUREMENT=de_DE.UTF-8
LC_IDENTIFICATION=de_DE.UTF-8
LC_ALL=

Closes #3

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.