Giter Club home page Giter Club logo

evseq's Introduction

evSeq

No sequence-function pair left behind.

Every Variant Sequencing (evSeq) is a library preparation and analysis protocol that slots neatly into existing workflows to enable extremely low-cost, massively parallel sequencing of protein variants. Designed for heterologously expressed protein variants arrayed in 96-well plates (or similar), this workflow enables sequencing all variants produced during a protein engineering or biochemical mutagenesis experiment at a cost of cents per variant, even for labs that do not have expertise in or access to next-generation sequencing (NGS) technology.

Read the Paper!

This repository accompanies the work "evSeq: Cost-Effective Amplicon Sequencing of Every Variant in Protein Mutant Libraries".

If you use this tool, please cite us:
@article{Wittmann2022,
author = {Wittmann, Bruce J and Johnston, Kadina E and Almhjell, Patrick J and Arnold, Frances H},
doi = {10.1021/acssynbio.1c00592},
journal = {ACS Synthetic Biology},
keywords = {directed evolution,machine learning,next-generation sequencing,protein engineering},
pages = {acssynbio.1c00592},
title = {{evSeq: Cost-Effective Amplicon Sequencing of Every Variant in a Protein Library}},
url = {https://pubs.acs.org/doi/10.1021/acssynbio.1c00592},
year = {2022}
}

Read the Docs!

For detailed information and interactive walkthroughs, read the docs at the evSeq website.

Quick links to common resources:

Biology
Computation

The evSeq workflow

Workflow A) evSeq amplifies out a region of interest that contains variability, attaches well-specific barcodes and adapters, and is ready for NGS.

B) All that's required to perform the evSeq laboratory procedure is:

  • a 96-well thermalcycler
  • standard PCR reagents and materials
  • access to an NGS provider
  • two 96-well plates of evSeq barcoding ("outer") primers
  • a pair of region-specific evSeq-compatible ("inner") primers
  • 96-well plate(s) of cultures containing DNA encoding protein variants
  • a 12-channel 10 µL pipette is also helpful; robotic support could be developed to replace many manual pipetting steps

That's it.

Due to the two-primer, culture-based PCR methodology employed by evSeq, only a new pair of inner primers needs to be ordered when targeting new regions/sequences and no DNA isolation needs to be performed.

C) Once the sequences are returned by the NGS provider, the computational workup can be performed on a standard laptop by users with little-to-no computational experience.

The amplicons prepared with evSeq can yield nearly 1000 high-quality protein variant sequences for just the cost of the multiplexed NGS run (typically ~$100 from commercial sequencing providers and much less from in-house providers).

Construct and visualize sequence-function pairs

SeqFunc Sequencing eight site-saturation libraries (768 wells) in a single evSeq run and combining this with activity data to create low-cost sequence-function data. A) Enzyme and active-site structure highlighting mutated residues. B) Heatmap of the number of identified variants/mutations ("counts") for each position mutated ("library") from processed evSeq data. C) Heatmap of the average activity ("normalized rate") for each variant/mutation in each library. D) Counts for a single library, also showing the number of unidentified wells. E) Activity for a single library, showing biological replicates. (Inset displays the mutated residue in this library.)

Installation

RECOMMENDED. Use the evSeq environment:

git clone https://github.com/fhalab/evSeq.git
cd evSeq
conda env create -f envs/evSeq.yml

evSeq is then installed inside the environment and can be run as described below when the evSeq environment is active.

This also installs a shortcut to the GUI on your Desktop (which can then be moved, e.g., to an Applications folder) which will run evSeq in the proper environment simply with a double click (see below).

Alternatively, you may install evSeq directly from PyPI via:

pip install evSeq

The correct packages should be automatically installed and a GUI shortcut is also made, but this is not guaranteed to work as you update your packages/dependencies in the future.

Updating

By default, evSeq is installed in non-dev mode. This means that changes to the code base on your computer will not be reflected come run-time. If you want an editable version of evSeq, install with the evSeq_dev environment (note, however, that this environment does not set exact versions of dependencies like the evSeq environment). We recommend installing in non-dev mode (i.e., using the evSeq environment). Finally, we also provide the evSeq_general environment file which is similar to evSeq_dev but does not install an editable version of evSeq. To update evSeq when installed in a non-dev environment, the environment must be recreated. The below commands will update evSeq. First, navigate the evSeq repository folder via command line and enter the below commands:

git pull
conda remove -n evSeq --all
conda env create -f envs/evSeq.yml

Usage

Command Line

Thanks to setuptools entry_points, evSeq can be accessed from the command line after installation as if it were added to PATH by running:

conda activate evSeq
evSeq refseq folder --OPTIONAL_ARGS ARG_VALUE --FLAGS

where refseq is the .csv file containing information about the experiment described above and folder is the directory that contains the raw .fastq files (.gz or unzipped) for the experiment.

For information on optional arguments and flags, run

evSeq -h

or visit the usage page.

GUI

evSeq is also installed with a GUI for greater accessibility. After installing evSeq, you will find a new shortcut/app/executable on your Desktop, which you can double-click to launch the evSeq GUI:

gui

More can be read about it here.

evseq's People

Contributors

brucejwittmann avatar kadinaj avatar palmhjell 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

Watchers

 avatar  avatar  avatar  avatar  avatar

evseq's Issues

Does evSeq support WSL?

Hi everyone,

I am trying install evSeq on my windows computer within its WSL2 (Windows Subsystem for Linux). I keep getting errors associated with gtk+, a package seemingly related to GUI. I wonder if evSeq is supposed to support WSL? Is there a way to install a GUI-free version of evSeq? Thank you so much in advance!

Tian

Lower int and float Sizes

The default int and float bitsize for numpy was used throughout, which is much higher than needed. We can get away with 8-bit or 16-bit in many cases. We should lower in future implementations to save on memory and processing time.

Refactor Alignment and Data Processing

The way we perform alignments could be much more efficient. We toss all reads with an insertion or deletion, so we are assuming a priori that the returned read aligns to the reference. As a result, there should be no need to perform a global alignment with Biopython -- we can just compare the reads to the reference, aligning the tail-ends of the reads to the appropriate ends of the reference. Reads with a given number of mismatches can then be discarded.

Doing this would allow us to (1) avoid the O(n^2) memory requirement for aligning to a reference of length n, (2) ordinally encode characters from the beginning, thus saving on memory, and (3) take advantage of vectorization with numpy to perform alignment QC and counting.

We may also want to play around with when exactly new processes are spawned for data analysis. Ideally, we want to send as little data as possible to the spawned processes, then return only what we need to comprehensively analyze all wells. Reorganizing code to maximize this transfer/memory efficiency should also reduce memory bloat.

Check GUI Still Works

@palmhjell @kadinaj I combined the shared GUI and CLI code into one file (we were asking for disaster whenever we had to change the defaults in both files...). CLI works fine. Can one of you check the GUI?

Parameters

Two things would improve quality of life and data management:

  1. Allow more automatic generation of the RefSeqs.csv file.
  • Just pass the plate (/default to plate 1?) and the ref sequences, and assume a full plate will be sent (A–H, 1–12).
  • This can be overwritten (especially useful to just pass a few wells for troubleshooting), but this being the default seems to make sense.
  1. Change the hard-coding of the GlobalParams.txt file location.
  • Currently requires it to be in the same directory as ssSeq_Parser (defined in ssSeq/GlobalSetup.py). It would be more convenient to have the code in one place (e.g., as a package) and the GlobalParams.txt file in a separate directory (along with the fastq sequences and RefSeqs.csv files themselves), thereby keeping everything together for a given experiment.
  • This might require changing some absolute/relative path behavior for, say, Output. Not sure though.

GUI Not Activating, Cannot Find Modules

When ND runs the GUI with

python ssSeqGuiLauncher.py it fails, returning the error given below.

image

The code should be able to find BioPython as it is in the conda environment.

Graphical diagnostics

Enhancement in the works: providing charts similar to the following in the standard output to assess the the quality of the sequencing data. As you can see, we forward read is quite good in both cases, but the reverse read is much worse in the "mix1" sample. Automatic generation of these charts (which are based directly on the MiSeq data and agnostic to the processing steps) would help troubleshooting.

lib3_forward
lib3_reverse
mix1_forward
mix1_reverse

Unable to find frame of reference sequence without variable site

Because the frame of the reference sequence is determined based on the placement of 'NNN' in the sequence (in GlobalSetup.py), this will fail in the event that one of your reference sequences doesn't have this.

Current work-around is to add a dummy 'NNN' codon in-frame to the relevant reference sequence and increase the number of variable sequences by one..

Might want to think of another way of coding this up?

Some enhancements!

First off just reiterating this is so amazing. I love it.

Okay down to business, in order of decreasing priority/increasing complexity:

  1. In the README, be more specific about how the reverse RefSeq is literally just as easy as it sounds (the 5' to 3' direction of the gene itself). I can make this change, just putting it here for reference.

  2. Output a third file in Summary, which is just the stats for the max in each well. (Easy code, can do it after, but also would be nice to just have.) Then if >95%, feel confident. If lower, check on a case-by-case basis if acceptable or meaningful.

  3. Add more automation in the sequence generation for the RefSeq.csv file. For example, if doing a single plate, allow passing 'all' in the well position, which would specify applying the ref sequences for all wells in a plate (A–H, 1–12). Or pass a list of plates if doing more than one.

  4. Let the parser read zipped files. (This may be as simple as just changing the function used for reading... https://stackoverflow.com/questions/12902540/read-from-a-gzip-file-in-python. It also might not...)

Unhandled exception encountered: 'cannot convert float NaN to integer'

Running the program on 20200814_TrpB_landscape data we first get an error about the heatmap and then this exception. Below is a screenshot. This occurs after processing the first plate and ends the run. No summary info is generated, and we only get quality histograms back. Note that the reverse reads are extremely low quality here.
image

The error log is not any more specific:

20200916-123223

refseq: C:\Users\kejoh\OneDrive - California Institute of Technology\ArnoldLab\Projects\NextGenSequencing\data\20200814_TrpB_landscape\exp2\DefaultRefSeqs.csv
source folder/fastq_f: C:\Users\kejoh\OneDrive - California Institute of Technology\ArnoldLab\Projects\NextGenSequencing\data\20200814_TrpB_landscape\exp2
fastq_r:
analysis only: False
input_readlength: None
troubleshoot mode: False
n jobs: 11
Q-score cutoff: 30
alignment filter: 0.5
output folder: C:\Users\kejoh\OneDrive - California Institute of Technology\ArnoldLab\Projects\NextGenSequencing\data\20200814_TrpB_landscape\exp2\ssSeq_Output\20200916-123223

Identified Seq File Pairs:
Forward Reads: {}
Reverse Reads: {}

Unmatched Files in Folder:

C:\Users\kejoh\OneDrive - California Institute of Technology\ArnoldLab\Projects\NextGenSequencing\data\20200814_TrpB_landscape\exp2\exp2_S187_L001_I1_001.fastq.gz
The identified read length for this run was: 151

Warning: All wells associated with 105X have a read depth <=10.Be careful comparing heatmaps between this plate and others.Be careful using this data; sequencing was not good.

Error Encountered:
Unhandled exception encountered: 'cannot convert float NaN to integer'

Need to update evSeq.yml dependencies

First of all, thanks for this tool! I just followed the recommended install instructions on the README and I'm getting the error below. It appears some of the dependencies have been updated recently.

evSeq refseqs/DefaultRefSeq.csv ../data/multisite_runs
/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/Bio/pairwise2.py:278: BiopythonDeprecationWarning: Bio.pairwise2 has been deprecated, and we intend to remove it in a future release of Biopython. As an alternative, please consider using Bio.Align.PairwiseAligner as a replacement, and contact the Biopython developers if you still need the Bio.pairwise2 module.
  warnings.warn(
Traceback (most recent call last):
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/bin/evSeq", line 33, in <module>
    sys.exit(load_entry_point('evSeq', 'console_scripts', 'evSeq')())
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/bin/evSeq", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/importlib/metadata.py", line 77, in load
    module = import_module(match.group('module'))
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 843, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/jlaw/Dev/bpms/evSeq/evSeq/cmd.py", line 3, in <module>
    from evSeq.interfaces import execute_evseq
  File "/Users/jlaw/Dev/bpms/evSeq/evSeq/interfaces.py", line 20, in <module>
    from evSeq.run_evSeq import run_evSeq
  File "/Users/jlaw/Dev/bpms/evSeq/evSeq/run_evSeq.py", line 7, in <module>
    from .data_visualization import (generate_qualplot,
  File "/Users/jlaw/Dev/bpms/evSeq/evSeq/data_visualization.py", line 10, in <module>
    import holoviews as hv
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/holoviews/__init__.py", line 12, in <module>
    from .annotators import annotate                         # noqa (API import)
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/holoviews/annotators.py", line 10, in <module>
    from panel.pane import PaneBase
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/panel/__init__.py", line 1, in <module>
    from . import layout # noqa
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/panel/layout/__init__.py", line 1, in <module>
    from .accordion import Accordion # noqa
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/panel/layout/accordion.py", line 5, in <module>
    from .base import NamedListPanel
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/panel/layout/base.py", line 11, in <module>
    from ..io.model import hold
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/panel/io/__init__.py", line 9, in <module>
    from ..config import config
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/panel/config.py", line 20, in <module>
    from .io.notebook import load_notebook
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/panel/io/notebook.py", line 39, in <module>
    from .resources import Bundle, Resources, _env, bundle_resources
  File "/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/panel/io/resources.py", line 23, in <module>
    from jinja2 import Environment, Markup, FileSystemLoader
ImportError: cannot import name 'Markup' from 'jinja2' (/Users/jlaw/Dev/miniforge3/envs/evSeq/lib/python3.8/site-packages/jinja2/__init__.py)

I found that if I update holoviews with pip install --upgrade holoviews, everything seems to work.

Output from pip:

$ pip install --upgrade holoviews
...
Installing collected packages: mdurl, xyzservices, uc-micro-py, markdown-it-py, Jinja2, mdit-py-plugins, linkify-it-py, bokeh, panel, holoviews
  Attempting uninstall: Jinja2
    Found existing installation: Jinja2 2.8
    Uninstalling Jinja2-2.8:
      Successfully uninstalled Jinja2-2.8
  Attempting uninstall: bokeh
    Found existing installation: bokeh 2.3.3
    Uninstalling bokeh-2.3.3:
      Successfully uninstalled bokeh-2.3.3
  Attempting uninstall: panel
    Found existing installation: panel 0.12.1
    Uninstalling panel-0.12.1:
      Successfully uninstalled panel-0.12.1
  Attempting uninstall: holoviews
    Found existing installation: holoviews 1.14.5
    Uninstalling holoviews-1.14.5:
      Successfully uninstalled holoviews-1.14.5
Successfully installed Jinja2-3.1.3 bokeh-3.1.1 holoviews-1.17.1 linkify-it-py-2.0.3 markdown-it-py-3.0.0 mdit-py-plugins-0.4.0 mdurl-0.1.2 panel-1.2.3 uc-micro-py-1.0.3 xyzservices-2024.4.0

AaIndStart in RefSeq file cannot tolerate negative values

When trying to analyze a tile in which the variable fragment starts immediately after the start ATG, a problem arises because the "AaIndStart" field of the RefSeqs.csv file cannot tolerate a negative value to allow amino acid indexing to match up with the annotated sequence.

Random questions

Hey guys,

I have a few questions from my run with the updated evSeq scripts:

  1. Is there an uninstall script for the local version, in particular for the GUI? Could be worth adding info to docs.
  2. For the BpIndStart and AaIndStart arguments, it gives the range as [0,inf], but I'm not sure how the value could be 0. It seems like that could only happen if there were a "-1" (or "-2" etc.) nt/codon included before the ATG, but in that case it seems like the range should be [-inf,inf].
  3. pip install evSeq not working
  4. Regarding the way that mutations are displayed in the plate map: I'm wondering if there's a better way of showing when there are multiple species in the same well. For example, look at DI01 well A07 here: if I'm interpreting it correctly, it seems like there are two populations in that well (?28V_?31W and ?52E_?56G) in a roughly 60:40 ratio (though correct me if that's the wrong interpretation). (Something similar happening in well D05). But in the plate map it just shows ?28V_?31W_?52E_?56G with a 0.38128 alignment frequency, which I interpreted as saying that 38% of reads show all four mutations, and the other 62% don't show all four. Or is the alignment frequency score more an indication of confidence than abundance? If the first interpretation is the right one, can we come up with a better way to plot the data so it's clear that there are multiple populations and what they are? I think you might be able to have multiple tooltips appear when you hover over a square.
  5. I don't think I really understand the Coupled/Decoupled definition, or the relationship between two mutations occurring together and paired-end reads if my reads don't overlap. Could you expand on that a bit more?
  6. In the docs about output, it says of the plate map: "Also note that, because the position information is not given, the output csv files in the previous section should be used for downstream processing," but it seems like the position information for each mutated residue is listed—what did you guys mean by this?

Thanks!

Alignment for mutagenesis at multiple sites

From my understanding of ssSeq parsing right now, reads are based on the forward and reverse parent sequences which include NNN at the site being saturated in the library. For this to be used in tile mutagenesis, I will need to determine at which position each read is mutated relative to the parent sequence, then determine the mutation.

I am happy to work on this implementation- maybe we can sit down some time in the near future to determine how best to implement this change.

Trim adaptor sequences if found in refseq

The probability that a new user (or, uh, myself) adds the adaptor sequence on each end of their refseq is very close to unity and results in catastrophic failure for sequence alignment and assignment, even with otherwise perfect data.

Given that the only issue is the refseq having these sequences (which are always the same and works without them), this is more of a code bug than user error.

Simple fix: if the adaptor sequence is found in the refseq, just trim it. Log it or whatever, but I can imagine nearly zero instances where this doesn't work out.

No one sees a platemap of #DEAD#DEAD#DEAD# and everyone is happy.

Known Limitations

evSeq expects no insertions or deletions relative to the reference sequence provided. Indeed, any read with a detected insertion or deletion is automatically discarded during QC. This works well for speeding up analysis of returned reads, but can lead to problems if (1) you expect insertions and deletions or (2) the best-scoring alignment of a read to the reference is one that opens a gap. There are currently no workarounds for problem 1. Problem 2 can be addressed by tuning the alignment parameters.

Alignment parameters are given as optional arguments; the parameter gap_open_penalty can be raised further to decrease the probability of problem 2 (i.e. score alignments such that those with gaps are scored poorly). Note that we have stress-tested the code with default alignment parameters against ~40,000 random DNA sequences with random mutation positions and found <10 instances of problem 2 (<0.025% of instances; all cases occurred when multiple mutations were placed next to (or near) one another at the end of the evSeq reads). The default evSeq alignment parameters are thus highly robust, but there are situations where they might need to be tuned. We strongly recommend that users evaluate the alignments returned by evSeq to make sure there are no unexpected insertions or deletions. Poor alignments will result in false sequencing negatives -- this can be particularly problematic if there are multiple variants in a well, and not all of them are recognized by the alignment (i.e., evSeq fails to recognize that there is a mixed well). As noted, such a situation would be exceedingly rare, but is worth being aware of. In many cases, alignment issues can be easily detected by reviewing both the decoupled and coupled files. To tell if the aligner has included insertions or deletions, (1) look for mutations present in the decoupled file that are not found in the coupled file and (2) look for "#DEAD#" wells that have more reads than the variable_count argument.

Support Mixed Readlengths

Some sequencing protocols provide different length forward and reverse reads (e.g, 100 bases in the forward, 200 in the reverse). evSeq currently assumes that both forward and reverse reads are the same length. Only sequencing runs with same-sized readlengths should currently be analyzed. There are some hacky ways to get around this, but they're not really tested. Future updates should resolve.

Kadina's sequencing run of high-quality primer dimer

I had several errors trying to process this dataset (which looks pretty rough) with ssSeq.

  • Type Error The first was with the calling of the "mode" as the read length. Do we need to specify this exactly anyway? I think there could be a work-around that doesn't require knowing a read length but still allows the package to run. When I ran sequencing without specifying a read length I got this error.
  • ValueError When I passed in a read length of 250 I got this error because I was 'trying to merge and object and float64 columns'. I only had reads of up to 150bp, so this was the wrong read length, but it would be nice to say that instead of throwing this error.
  • IndexError I got this error when I passed in a read length of 150 (the actual length of my longest reads). Nothing aligned more than maybe 30-40 base pairs though. Because the error was 'index 40 out of bounds for axis 0 with size 40' I imagine that the longest read that aligned was only 40 bases but the program was searching for 150 bases.

file location on server: /group_files/Kadina/NGS_results/TrpB_epistatic_landscape/20200131 or /group_files/Kadina/NGS_results/TrpB_epistatic_landscape/20200131.zip

Data Processing error

It's able to load and qc the libraries but after that it sends me this error: Unhandled exception encountered: ''NoneType' object has no attribute 'sort_values''

Run fails if "NNN" not detected within both the forward and reverse reads

Designing primers, if there is no NNN within the 150bp range of the forward or reverse read the program fails. The program should still proceed since you do not need to have an NNN necessarily. For example, I have sequencing where there is only one randomized site and it is not captured by the reverse read.

LCMS() needs some fine tuning

Delimiter auto assignment (and explicit assignment) aren't working well. Explicit assignment as argument leads to delim referenced before assignment bug.

Question/Error fixing

Hi,
Thank you for developing this!
I have been trying to give this a try on some of our data and I keep getting this error:

Unmatched Files in Folder:


Error Encountered:
Unhandled exception encountered: ''Index''

I had to change the index on the first row in index_map.csv based on the indexes we use, so am not sure if that is what is causing the error.

Reads with Length Longer than Refseq Thrown Away

evSeq discards reads with insertions and deletions, and a read longer than the refseq has (relative to the refseq) a very large insertion. These reads are thus all thrown away. Conditional should be added to only use a portion of the read up to the refseq size.

Reimplement Pytests

I've probably broken the pytest workflow with the addition of stress testing code. Specifically, I used "test" in the name of a lot of files that should not be run by pytest. We will need to tell pytest to ignore certain folders/files. This should be easy to implement with a bash script.

Make Alignment Penalties Tunable

Alignment penalties are currently hard-coded. These were chosen to maximize generalizability (i.e., they work in almost all cases for evSeq); however, there are some edge cases (e.g., when mutations are right on the end of a read) that can result in the aligner preferentially adding indels over mismatches. When indels are added, evSeq will throw out otherwise perfectly good reads, sometimes causing it to label wells as dead when they shouldn't be. The good news is that this is easily diagnosable from the alignments output.

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.