Giter VIP home page Giter VIP logo

lib-font's Introduction

LibFont - lifting the hood on your fonts

If you're looking for the (really) old ES5 version of LibFont, when it was still called "Font.js", you should be able to find it here.

Also, if this made a difference in your dev life, consider (temporarily, even?) becoming a patron of my work over on https://www.patreon.com/bezierinfo, or send a one-time donatation to help keep this project funded. Any amount is appreciated!

td;dr:

Node installation

Use npm install lib-font, after which the package can be imported using import { Font } from "lib-font".

Note that there is no legacy commonjs version of this library available. Node LTS 14 and above have native support for ES modules - Have a look at babel's transform-modules-commonjs plugin if you really have no choice but to use commonjs.

Browser "installation"

You can either use the pre-built lib-font.browser.js bundle, or you can download the code and unpack it into a vendor directory, then point to the lib-font.js file in that directory. Either way, remember to tell the browser that this is modern ES module code by using type="module" in the script tag, and be kind to your users and remember the async attribute, too:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>...</title>
    ...
    <script type="module" src=".../lib-font.js" async></script>
  </head>

  <body>
    ...
  </body>
</html>

(Although you'll generally want to use this in something so your HTML would look more like <script type="module" src="./js/myscript.js" async></script> with the myscript.js file having an import { Font } from "./lib-font"; instead)

Note that there is no legacy ES5 version of this library available, because there are no ES5 browsers anymore, every single still in support browser supports ES Modules, so if you really need to target dead browsers have a look at babel.

Introduction

What if you could actually inspect your fonts? In the same context that you actually use those fonts?

That's what this is for:

// On the Node side: import { Font } from "lib-font";
// In browser-ESM context: import { Font } from "your/js/dir/lib-font-browser.js";
//
// Also note that on the browser side, you can either use the ESM import 
// or you can load the library "on its own" using its own script tag,
// which sets up a global `Font` object for you to use.

// Create a font object
const myFont = new Font(`Adobe Source Code Pro`);

// Assign event handling (.addEventListener version supported too, of course)
myFont.onerror = evt => console.error(evt);
myFont.onload = evt => doSomeFontThings(evt);

// Kick off the font load by setting a source file, exactly as you would
// for an <img> or <script> element when building them as nodes in JS.
myFont.src = `./fonts/SourceCodeVariable-Roman.otf`;

// When the font's up and loaded in, let's do some testing!
function doSomeFontThings(evt) {
    // We can either rely on scoped access to font, but because the onload function
    // is not guaranteed to live in the same scope, the font is in the event, too.
    const font = evt.detail.font;

    // First, let's test some characters:
    [`a`, `→`, `嬉`].forEach(char => console.log(`Font supports '${char}': ${
        font.supports(char)
    }`));

    // Then, let's check some OpenType things
    const GSUB = font.opentype.tables.GSUB;

    // Let's figure out which writing scripts this font supports:
    console.log(`This font supports the following scripts: ${
        `"${GSUB.getSupportedScripts().join(`", "`)}"`
    }`);

    // DFLT is a given, but let's see if `latn` has any special language/system rules...
    const latn = GSUB.getScriptTable('latn');
    console.log(`Special langsys for "latn": ${
        `"${GSUB.getSupportedLangSys(latn).join(`", "`)}"`
    }`);

    // Wow, "Northern Sami" support? Really? Which OpenType features does that use?
    const nsm = GSUB.getLangSysTable(latn, "NSM ");
    console.log(`OpenType features for the Northern Sami version of latin script:`,
        `"${GSUB.getFeatures(nsm).map(f => f.featureTag).join(`", "`)}"`
    );

    // Oh wait, this is a variable font, isn't it.
    console.log(`This is a variable font: ${!!font.opentype.tables.fvar}`);

    // Which axes does it support?
    console.log(`This variable font supposed the following axes: ${
        `"${font.opentype.tables.fvar.getSupportedAxes().join(`", "`)}"`
    }`);
}

You can also pass in a file directly, e.g. using the HTML Drag and Drop API. In order to deal with the font as bytecode, you can use the font.fromDataBuffer(bytecode, filename) function to kick off the font loading:

const myFont = new Font(`Adobe Source Code Pro`);

// Grab file frop drop event or file upload
const file = e.target.files[0];

// Use FileReader to, well, read the file
const reader = new FileReader();
reader.readAsArrayBuffer(file);

reader.onload = function() {
    // Pass the buffer, and the original filename
    myFont.fromDataBuffer(reader.result, file.name);
    myFont.onload = e => {
        // ...
    };
};

What about a tag/element?

This library does not offer a <font src="..." ...> tag, in part because proper custom elements must have a hyphen in their name, but primarily because the only DOM related work that a <font> tag would be useful for is already handled by <style> (for declaring a @font-face) and <link> (for importing a @font-face stylesheet).

API

The uplifted library API is still pending... As of right now, a lot of the functions and properties are pretty easily found if you know your way around an OpenType font already by looking at the source as well as the tests, but that's not ideal - API docs will be forthcoming but can always use help.

That said, this section will keep getting expanded as the API gets consolidated.

Font

const f = new Font(fontFamilyName, optionsObject)

The family name is use for stylesheet building, and the options object can contain the following fields:

fieldname type default description
skipStyleSheet boolean false Determines whether not to build the @font-face stylesheet.
styleRules object {} A set of key/value pairs representing CSS rules to add to the @font-face declaration
errorOnStyle boolean false Whether to error out, or merely warn, if the font type cannot be determined from the src assignment.

f.onerror = evt => ... / f.addEventListener('error', evt => ...)

Error handling for anything font related

f.onload = evt => ... / f.addEventListener('load', evt => ...)

Load handling for anything font related

f.src = ...

Bind a font to a source URL. This can be a fully qualified URL, a relative URL, a Blob URL, or a Data-URL.

const actualFont = f.opentype

The actual opentype font representation is font in the .opentype property.

const fontTables = f.opentype.tables

This is the main access point for any font table, where each table is accessed directly by name. E.g. in order to access the cmap table, you use const cmap = f.opentype.tables.cmap, GSUB is const GSUB = f.opentype.tables.GSUB, etc.

Development

The main entry point for this library is ./lib-font.js, with all code dependencies found in the ./src directory,.

Testing

The npm test command should be all you need in order to run the tests, provided you ran npm install first, of course.

  • Node based testing uses Jest tests, found in the ./testing/node dir.
  • Browser based testing uses Puppetter, found in the ./testing/browser/tests dir.

Compatibility

This library is designed to run both in any browser and version of Node.js versions that supports es modules.

  • Browsers: see the caniuse matrix (tl;dr: basically everything except IE11).
  • Node: native support as of v14 (--experimental-modules runtime option as of v12).

Preemptive answers to questions

Why don't woff/woff2 work?

They do, but they rely on having the gzip inflater and brotli decoder libraries loaded. You can find those in the ./lib dir, as they are optional: without them regular parsing still works fine, but with inflate loaded, woff parsing will succeed, and with unbrotli loaded, woff2 parsing will succeed.

To make this work on your own pages, add the following bit to your document head, with the appropriate path to these two libraries, of course:

    <script src="./lib/inflate.js" defer></script>
    <script src="./lib/unbrotli.js" defer></script>

Why can't this draw stuff??

Because you already have lots of text shaping engines available. In the browser, it's literally your browser (you can already draw all the text you need, properly shaped and typeset, both in HTML and on a Canvas). In node, it's whatever graphics library you're using to already draw everything else you need to draw.

Proper OpenType text shaping is incredibly complex and requires a lot of specialized code; there is no reason for this library to pretend it supports text shaping when it's guaranteed to do it worse than other technologies you're already using.

Why would I use this instead of OpenType.js or Fontkit or something?

I don't have a good answer to that. Those are some great projects, you probably should use them if they do what you need? The reason I needed this is because it doesn't do text shaping: it just lets me query the opentype data to get me the information I need, without being too big of a library. And I've written enough OpenType parsers to know how much code goes into the actual shaping.

How do I use this with webpack?

By first remembering that bundling was born out of JS not having a module system, where we needed to deliver code in a way that required a single <script> element instead of tens or even hundreds of script tags that all had to load in a specific order - an order that could not be guaranteed so needed additional code to manage execution dependencies. Bundling solved that problem, but at a terrible price: it broke browser caching. Your well organized code consisting of individual files for each role was now a single, megabyte-plus monster file and if you needed to change even a single letter, you'd invalidate the cache entry for that entire bundle. Chunking tried to solve that, but was a classic "deal with the symptom instead of addressing the problem" solution. The real solution landed quite a while ago now: JS got its own module system called ES modules, often just referred to as "ESM", and every single browser on the market supports it. Bundling has not been necessary since the summer of 2022, when Microsoft finally killed off the Internet Explorer line of browsers, removing the last reason people still had for using things like Browserify or Webpack (and really, it hasn't been necessary since a few years prior, because plenty of sites had the luxury of just not bothering to support IE once Edge was available concurrently, because even Microsoft was vocal about the fact that IE was going to get killed off for being hopelessly out of date and incompatible with the web).

This is something you should give serious thought to: bundling is a legacy practice, and if your codebase permits it, stop bundling. You don't need to, and your pages and even web apps will be more performant if you don't.

Second, if you're somehow still stuck with "needing" to bundle, consider switching to esbuild, which is remarkably straight forward to switch to from webpack, even with complex configurations, and puts your project on a modern and both (much) faster and better documented bundler instead. JS tooling like formatters, bundlers, and minifiers should not themselves be written in JS.

However, if you're absolutely stuck with webpack, then as least be on the latest version of Webpack, and tell it to ignore fs and zlib.

// webpack.config.js
module.exports = {
    ...
    resolve: {
        fallback: {
            "fs": false,
            "zlib": false
        },
    }
}

These modules are not loaded "up front" by lib-font, they are dynamic imports that only run when necessary, so if you're running lib-font in the browser those imports will never trigger, and the fact that webpack didn't bundle anything in for them will never result in a code failure or error. Simply make webpack ignore them, because the browser will, too.

Alright, what if I have opinions?

Drop me a message! @TheRealPomax should do nicely, but if you want to have an in-depth discussion, I'd recommend filing an issue, since 280 characters per message is not really sufficient to dig into OpenType details.

And if I just want to use this?

This code is MIT licensed, do whatever you want with it.

lib-font's People

Contributors

belluzj avatar keyamoon avatar pascalw avatar pomax avatar robertjanes avatar roeln avatar yisibl 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

lib-font's Issues

Internet Explorer support

There is no word about Internet Explorer support in code, the documentation, or the demo page. As the Object.defineProperty is not supported in IE8 and earlier, at least this information should be indicated. Maybe do the same to other browsers that either don't support canvas or don't support Object.defineProperty.

Load fonts Cross Domain

Does this work already? I only see XMLHttpRequests in the code. I would think that this use case is one of the more common ones, as a lot of people load fonts from the Google Font Library or equivalent.

Add instruction on running test/example

Because Font.js is loaded as module, it needs to be served instead of being accessed from the filesystem. Maybe add a note explaining this to index.html?

(Perhaps including the python -m SimpleHTTPServer quick tip?)

Or is there a way to get this going from the file system? Maybe by offering a rolled-up version in a dist folder?

Possible incorrect this scope for error handling.

On line 268-270 the onerror function is executed.

var error = function (msg) {
  this.onerror(msg);
};

For a 404, I'm seeing (this == window) and not the expected Font object. The following works.

var _font = this;
var error = function (msg) {
  _font.onerror(msg);
};

I didn't want to issue a pull request for this because that's not a great solution, and I'm not even sure where the root of the problem lies.

I'm invoking the font like so:

$p.Font = function(data) {
    this.data = data;
}

$p.Font.prototype.preload = function(callback) {
    var font  = this;
    var _font = new Font();
    _font.onload = function() {
        console.log(font.data.url+' loaded');
    }
    _font.onerror = function(err) {
        console.log(font.data.url+' error '+err)
    }
    _font.src = font.data.url;
    font.Font = _font;
}

The $p.Font wrapper is just for my own application loader.

Timing out due to empty character

It seems that the printChar it uses for testing the font is an empty string ("").

On line 425:

printChar = String.fromCharCode(endChar);

Where endChar is 129 for the following Optima TTF font.

I assume the fix in this instance is to detect if the yielded printChar is empty, and if so, to revert to the printChar default of A.

Can we use this font to draw on canvas?

I tried this code to draw on canvas but no result:

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px "+font.fontFamily;
ctx.fillText("Hello World", 10, 50);

License?

What license is this project available under? :D

Testing character throws an error

In the example there is this line of code:

     [`a`, `→`, `嬉`].forEach(char => console.log(`Font supports '${char}': ${
         font.supports(char)
     }`));

If it's not commented out, the font won't get loaded.
Message:

Event {type: "error", detail: TypeError: this.get is not a function. (In 'this.get(tableID)', 'this.get' is undefined), msg: "Failed to load font at ./fonts/SourceCodeVariable-Roman.otf.woff2", __mayPropagate: true}

If I comment it out, there is no error. But why does it say that the font cant get loaded? How can I test which characters a font file has?

Path to simple-table.js

image

The file is at src/opentype/tables/simple-table.js so either move it or change paths everywhere, whatever you intention was?

Also a request for lazy.js errors out similarly?

Make Font.js run on Node.js

The main reasons it can't right now is because it relies on window/document. We should be able to shim the functions we need where necessary, and conditionally "just do nothing" if there is no browser context to work in.

What we don't need: "browser bundling" =D

Implement all tables

simple

  • OS/2
  • SVG
  • head
  • hhea
  • hmtx
  • maxp
  • name
  • post

cmap

  • CMAP
  • subtable 0
  • subtable 2
  • subtable 4
  • subtable 6
  • subtable 8
  • subtable 10
  • subtable 12
  • subtable 13
  • subtable 14

advanced

  • BASE
  • GDEF
  • GPOS
  • GSUB
  • JSTF
  • MATH

bitmap

  • CBDT
  • CBLC
  • EBDT
  • EBLC
  • EBSC
  • sbix

bitmap formats

  • format1
  • format2
  • format3
  • format4
  • format5
  • format6
  • format7
  • format8
  • format9
  • format17
  • format18
  • format19

cff

  • CFF
  • CFF2
  • VORG

color

  • COLR
  • CPAL

other

  • DSIG
  • LTSH
  • MERG
  • PCLT
  • VDMX
  • hdmx
  • kern
  • meta
  • vhea
  • vmtx

ttf

  • cvt
  • fpgm
  • gasp
  • glyf
  • loca
  • prep

variation

  • HVAR
  • MVAR
  • STAT
  • VVAR
  • avar
  • cvar (but see #55)
  • fvar
  • gvar

Errors in README example

This doesn't work ("GSUB.lookupList.getSupportedScripts is not a function")

// Let's figure out which writing scripts this font supports:
console.log(`This font supports the following scripts: ${
    `"${GSUB.scriptList.getSupportedScripts().join(`", "`)}"`
}`);

but this does:

// Let's figure out which writing scripts this font supports:
console.log(`This font supports the following scripts: ${
    `"${GSUB.getSupportedScripts().join(`", "`)}"`
}`);

(Removing the scriptList).

The getTable example errors too (also "is not a function"), couldn't get it to work tweaking the code:

// DFLT is a given, but let's see if `latn` has any special language/system rules...
console.log(`Special langsys for "latn": ${
    `"${GSUB.scriptList.getTable('latn').getSupportedLangSys().join(`", "`)}"`
}`);

Add custom tag parsing plugins

Font.register("tag", parsingFunctionReturningATableObject) would be nice, for checking fonts that use experimental stuff. Like a fictional GMOD table.

Bower fails to install 0.2.5

bower Font.js#~0.2.5        not-cached git://github.com/Pomax/Font.js.git#~0.2.5
bower Font.js#~0.2.5           resolve git://github.com/Pomax/Font.js.git#~0.2.5
bower Font.js#~0.2.5      ENORESTARGET No tag found that was able to satisfy ~0.2.5

May I suggest creating release tags for the releases?

"Timing out" is logged

Hi, I tried using your plugin. I'm loading several fonts by doing the following on document ready:

preloadFonts([
        '/path/fonts/Font.otf'
        '/path/fonts/Font2.otf'
]);

function preloadFonts(arrayOfFonts)
{
    $(arrayOfFonts).each( function(i, src) {
        var loadFont = new Font();
        loadFont.src = src;
        loadFont.onload = function () {
            console.log('Font "'+ src +'" loaded');
        }
    });
}

I'll get the console.log that the font is loaded, but I'm also getting a log "Timing out", which (correct me if I'm wrong) means that the font isn't loaded correctly. And when I start to display something where the font is used I first see a standard webfont for a few seconds.

Any idea what I can do about it? Thanks!

Tighten up the source

  • rewrite as much this.var1 = p.type; this.var2 = p.type; to this.load({ var1: p.typ, var2: p.type, ... }) as possible

WOFF support

I was trying this library with some Google Fonts and because it only serves your browser the CSS for the best/latest format your browser can support, it is a bit of a pain to get to anything other than the WOFF file's URL.

It might be more effort to implement than it is worth, but support for it would be nice.

Rollup syntax

npx rollup --no-treeshaking --format=esm Font.js > Font.rolled.js

should be

npx rollup --no-treeshake --format=esm Font.js > Font.rolled.js

At least, On My Machine™

Questions about asynchronous font loading

EDIT: Sorry, please disregard this comment and see the next comment

Hi Pomax,

Thanks for the cool library - I've been looking for a way to measure text before rendering to the DOM for ages, and it looks like this may be it!

However, I am having an issue with measuring system fonts which are already loaded. Specifically, it seems like setting the src property on the font kicks off an asynchronous process, but there is no way to know when it is done and ready to measure. So if I run the following code:

var font = new window.Font();
font.fontFamily = "Helvetica Neue";
font.onload(() => { console.log('loaded'); });
font.src = font.fontFamily;
console.log(font.measureText('ok', 12));

It logs false, and never logs "loaded". The only way I have gotten it to actually work with system fonts is to use setTimeout, eg. this works fine:

setTimeout(() => console.log(f.measureText('ok', 12)), 1000);

However, this is unfortunately pretty untenable for use in my application code. Is there another callback I can use, or any way to make this work synchronously? Thanks for taking a look.

Replace lazy() with JIT parsing

Currently, lazy(...) will lazy load in arrays and complex structures as a whole, which means that while we don't take up useless memory initially, we will be taking up a lot more memory than necessary to service data extraction calls: cmap subformat 4, for example, will load the start/end/delta/range arrays into memory when accessed, rather than binding an array-like that does JIT extraction instead.

Is that disastrous? No.

Is it kind of silly? Yes.

InvalidCharacterError

I'm getting the following error:

Uncaught InvalidCharacterError: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

When I use this as test data:

font.fontFamily = "Roboto Condensed";
font.src = "http://themes.googleusercontent.com/static/fonts/robotocondensed/v9/Zd2E9abXLFGSr9G3YK2MsDR-eWpsHSw83BRsAQElGgc.ttf";

btw, I got all the .ttf URLs for a google font using this:

curl http://fonts.googleapis.com/css?family=Roboto+Condensed:100,100italic,200,200italic,300,300italic,400,400italic,500,500italic,600,600italic,700,700italic,800,800italic,900,900italic

Then you can just replace Roboto+Condensed with whatever Google Font you're interested in.

optional CFF / CFF2 parsing?

While this lib may not be intended to be a text shaper, it might be useful to offer a separate CFF/CFF2 parser that can be loaded alongside Font.js, to allow Font.js to dig into the CFF/CFF2 blocks (without doing charstring interpretation), to add additional "raw data" inspection of the font.

Add EBLC subtables

  • IndexSubTable1
  • IndexSubTable2
  • IndexSubTable3
  • IndexSubTable4
  • IndexSubTable5

Support for measuring any font already available to the browser.

It seems Font.js only supports remote fonts. The browser's built in font metrics capabilities for already-available fonts is terrible (canvas' measureText() only returns the width). It would be amazing if I could set font.src = '18pt bold helvetica' and then get accurate metrics back.

It looks like this could work pretty easily as you are already using canvas to measure the font rather than some data embedded in the font file itself.

One thing missing is leading. I've found easiest and most accurate measure is .offsetHeight/2 of a 2 line div with line-height: 1.

Minified version

Thank you for this useful library. A minified version of Font.js would be welcome.

Uploading font

Hello,
im using a canvas, where i can upload images into, simple with Image() object, by setting the readed data (by using FileReader) to image.src. With that i can simply upload the image.

Image example:
var imgObj = new Image();
imgObj.src = event.target.result;

Font.js doesnt support exactly this, so you can't simply load them on site, like the images, because it doesnt support the font.src.

So my question is, is it even possible to upload font on site, if yes, how to set FileReader's data to Font()?

Thank you

Font height gets too big when font is bigger then 250 pt

Hi, guys.

I got this issue when trying to measure text with font size bigger than 250 pt.

Here is a sample...

fontSize: 235
fontMetrics.height: 172

fontSize: 240
fontMetrics.height: 176

fontSize: 245
fontMetrics.height: 180

fontSize: 250
fontMetrics.height: 183

fontSize: 255
fontMetrics.height: 1020

fontSize: 260
fontMetrics.height: 1040

fontSize: 265
fontMetrics.height: 1060

Thanks.

Merge with plumin?

I still think JavaScript needs a Font object, but at this point rewriting it from scratch so that it's backed by OpenType.js is far more sensible

You know, http://www.pluminjs.com provides a Font() object. Maybe merging the details of this into plumin is best?

trouble with remote icon font

Hello,

Does font.js work with icon fonts?

I am trying to use Font.js to detect if a remote icon font is loaded or not. The font family is "Ionicons" and I am loading it through a stylesheet. I know that the font is getting loaded, because the glyph icon is showing up. But Font.js never detects that it is loaded.

Any ideas?

Here is the test case.

<!doctype html>
<html lang="us">
<head>
    <meta charset="utf-8">
    <link href="http://code.ionicframework.com/ionicons/1.5.2/css/ionicons.min.css" rel="stylesheet" type="text/css">
</head>
<script src="Font.js"></script>

<script>
    var font = new Font();
    font.onload = function(){
        console.log("loaded");
    };
    font.fontFamily = "Ionicons"
    font.src = font.fontFamily;
</script>
<!-- this does display the correct character -->
<i class="ion-arrow-right-a"></i>=
</body>
</html>

do some smart metrics tesselation for large strings

Since the preallocated canvas is em × em pixels, it's possible that someone will use this to measure a wide, wide string. When that happens, metrics computation could conceivably be done by measuring string fragments, and then tesselating the results. Somehow.

Get supported characters

What'd be the intented way to get a list of supported chars from the cmap table, other than looping over every unicode value and passing it to supports()?

I figured I could use startCode and endCode to get unicode ranges, but it there appears to be some noise in those arrays, e.g.:

[32, 38, 44, 48, 58, 63, 65, 91, 95, 97, 105, 160, 171, 187, 191, 8211, 8216, 8220, 8230, 8249, 65535, 0, 0, 0, 45, 9, 65534, 65474, 0, 65533, 65468, 0, 0, 65441, 65426, 65407, 57415, 57392, 57386, 57375, 57365, 1]

(Last supported character is 8249, after which it jumps to 65535 and some zeroes etc.)

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.