A navigation aid (aka, router) for the browser in 850 bytes~!

Overview
navaid
A navigation aid (aka, router) for the browser in 865 bytes~!

Install

$ npm install --save navaid

Usage

const navaid = require('navaid');

// Setup router
let router = navaid();
// or: new Navaid();

// Attach routes
router
  .on('/', () => {
    console.log('~> /');
  })
  .on('/users/:username', params => {
    console.log('~> /users/:username', params);
  })
  .on('/books/*', params => {
    console.log('~> /books/*', params);
  });

// Run as single instance
router.run('/');
//=> "~> /"
router.run('/users/lukeed');
//=> "~> /users/:username { username: 'lukeed' }"
router.run('/books/kids/narnia');
//=> "~> /books/* { wild: 'kids/narnia' }"

// Run as long-lived router w/ history & "<a>" bindings
// Also immediately calls `run()` handler for current location
router.listen();

API

navaid(base, on404)

Returns: Navaid

base

Type: String
Default: '/'

The base pathname for your application. By default, Navaid assumes it's operating on the root.

All routes will be processed relative to this path (see on()). Similarly, while listening, Navaid will not intercept any links that don't lead with this base pathname.

Note: Navaid will accept a base with or without a leading and/or trailing slash, as all cases are handled identically.

on404

Type: Function
Default: undefined

The function to run if the incoming pathname did not match any of your defined defined patterns.
When defined, this function will receive the formatted uri as its only parameter; see format().

Important: Navaid only processes routes that match your base path!
Put differently, on404 will never run for URLs that do not begin with base.
This allows you to mount multiple Navaid instances on the same page, each with different base paths. 😉

format(uri)

Returns: String or false

Formats and returns a pathname relative to the base path.

If the uri does not begin with the base, then false will be returned instead.
Otherwise, the return value will always lead with a slash (/).

Note: This is called automatically within the listen() and run() methods.

uri

Type: String

The path to format.

Note: Much like base, paths with or without leading and trailing slashes are handled identically.

route(uri, replace)

Returns: undefined

Programmatically route to a path whilst modifying & using the history events.

uri

Type: String

The desired path to navigate.

Important: Navaid will prefix your uri with the base, if/when defined.

replace

Type: Boolean
Default: false

If true, then history.replaceState will be used. Otherwise history.pushState will be used.

This is generally used for redirects; for example, redirecting a user away from a login page if they're already logged in.

on(pattern, handler)

Returns: Navaid

Define a function handler to run when a route matches the given pattern string.

pattern

Type: String

The supported pattern types are:

  • static (/users)
  • named parameters (/users/:id)
  • nested parameters (/users/:id/books/:title)
  • optional parameters (/users/:id?/books/:title?)
  • any match / wildcards (/users/*)

Note: It does not matter if your pattern begins with a / — it will be added if missing.

handler

Type: Function

The function to run when its pattern is matched.

Note: This can also be a Promise or async function, but it's up to you to handle its result/error.

For patterns with named parameters and/or wildcards, the handler will receive an "params" object containing the parsed values.

When wildcards are used, the "params" object will fill a wild key with the URL segment(s) that match from that point & onward.

let r = new Navaid();

r.on('/users/:id', console.log).run('/users/lukeed');
//=> { id: 'lukeed' }

r.on('/users/:id/books/:title?', console.log).run('/users/lukeed/books/narnia');
//=> { id: 'lukeed', title: 'narnia' }

r.on('/users/:id/jobs/*').run('/users/lukeed/jobs/foo/bar/baz/bat');
//=> { id: 'lukeed', wild: 'foo/bar/baz/bat' }

run(uri)

Returns: Navaid

Executes the matching handler for the specified path.

Unlike route(), this does not pass through the history state nor emit any events.

Note: You'll generally want to use listen() instead, but run() may be useful in Node.js/SSR contexts.

uri

Type: String
Default: location.pathname

The pathname to process. Its matching handler (as defined by on()) will be executed.

listen(uri?)

Returns: Navaid

Attaches global listeners to synchronize your router with URL changes, which allows Navaid to respond consistently to your browser's BACK and FORWARD buttons.

These are the (global) events that Navaid creates and/or responds to:

  • popstate
  • replacestate
  • pushstate

Navaid will also bind to any click event(s) on anchor tags (<a href="" />) so long as the link has a valid href that matches the base path. Navaid will not intercept links that have any target attribute or if the link was clicked with a special modifier (eg; ALT, SHIFT, CMD, or CTRL).

uri

Type: String
Default: undefined

(Optional) Any value passed to listen() will be forwarded to the underlying run() call.
When not defined, run() will read the current location.pathname value.

unlisten()

Returns: undefined

Detach all listeners initialized by listen().

Note: This method is only available after listen() has been invoked.

License

MIT © Luke Edwards

Comments
  • Calling listen() with an optional URL to be used on its internal run() call

    Calling listen() with an optional URL to be used on its internal run() call

    Hello, Luke!

    I am implementing navaid as a long-lived router on an app that will be used both on web and smartphones (through Cordova).

    Is there an option on navaid to avoid the automatic call of run() when calling listen() or a way to provide a specific URL to this first call, like / instead of the current URL?

    This helps my app to run fine on smartphones as well, because otherwise the run() call will fail with the initial URL provided by Cordova, that is something like file:///home/user/app/directory/index.html.

    I used Page.js to to this before, and on the smartphones I used its dispatch: false option to avoid this firs "run". But Navaid is so incredibly smaller that I prefer it over Page.js.

    Thanks again!

    opened by paulocoghi 18
  • Nested routes info and problem reproduction

    Nested routes info and problem reproduction

    I apologize in advance if I'm wrong to open the issue and I shouldn't have done it here. But I think it really concerns the basics of Navaid.

    I'm also ready to open and update a wiki page for all newcomers like me.

    THE PROBLEM:

    I started from svelte-demo (https://github.com/lukeed/svelte-demo) and I'm trying to use nested routes for a list/detail view.

    REPRODUCTION: https://codesandbox.io/s/quizzical-dirac-2d0qy

    To come to the problem you should:

    • open the console from the tab on the bottom
    • click on "Go to Teams Page"
    • click on "Go to Team 1 Page" (or others)
    • click on "Go to Team 1 Page" (or others) from the list
    • as you can see in console until now just four messages from "App draw()" and one "PageTeamRoute draw()"
    • now you can clear the console
    • click on "Go to Player 1 Page" (or others) from the list
    • you can see now the problem: 4 messages in console:

    image

    Why?

    Am I correctly using Navaid with nested routes?

    Is this correct in App.svelte?

    .on("team/*", obj => draw(PageTeam, obj))
    
    opened by frederikhors 16
  •  Error: UMD and IIFE output formats are not supported for code-splitting builds.

    Error: UMD and IIFE output formats are not supported for code-splitting builds.

    I am following the example in the template provided after creating an app from the official svelte demo and I received the above ^ error when I set my rollup configuration file format to iife.

    input: 'src/main.js', output: { sourcemap: true, format: 'iife', name: 'app', file: 'public/bundle.js' },

    Or is this a rollup issue?

    question 
    opened by Naragod 15
  • catch urls like /team/:teamID and /team/:teamID* (wildcard)

    catch urls like /team/:teamID and /team/:teamID* (wildcard)

    Coming from this example: https://codesandbox.io/s/reverent-tesla-c0kq0 I would like to understnad if this is possible in Navaid now:

    const router = Navaid()
        .on("/", () => draw(PageHome))
        .on("/teams", () => draw(PageTeamList))
        .on("/team/:teamID/*", obj => draw(Team, obj))
        .listen();
    
    • using .on("/team/:teamID/*", obj => draw(Team, obj)) doesn't catch urls like "/team/1"
    • using .on("/team/*", obj => draw(Team, obj)) catch urls like "/team/1" but as params in Team component I need the :teamID parameter which is wild in this case; the problem is if the URL is eg. like "/team/1/2/56/8" wild is 1/2/56/8 which is a wrong var in my Team component code.

    UPDATE:

    I need also something like this to catch: /team/1/shirt/5.

    Is there a way to catch both using something like /team/:teamID* where * here is a wildcard after :teamID?

    I hope I was clear. :)

    opened by frederikhors 14
  • Svelte update (3.5.1 > 3.5.2) and BOOOM! (problems, not joys)

    Svelte update (3.5.1 > 3.5.2) and BOOOM! (problems, not joys)

    Taking your https://codesandbox.io/s/reverent-tesla-c0kq0 from https://github.com/lukeed/navaid/issues/13.

    • If you upgrade to 3.5.1 is ok:

    (one click on "Go to Teams Page") image

    • If you upgrade to 3.5.2 is not:

    (one click on "Go to Teams Page") image

    What can it be?

    UPDATE:

    FIRST PROBLEM

    I cannot navigate anymore.

    Until 3.5.1 you can navigate like this:

    1. Being in Home ("/")
    2. click on "Go to Teams Page" ("/teams")
    3. click on "Go to Team 1 Page" ("team/1")

    With 3.5.2 you can't.

    You can do 1 and 2 but at the step 3 you see nothing.

    If you are on the page "team/1" and reload using codesandbox's preview icon it works.

    SECOND PROBLEM

    In one of my projects the error is even more frightening:

    TypeError: Cannot read property '$$' of undefined
    
    opened by frederikhors 8
  • Consider support for hash-based routing

    Consider support for hash-based routing

    For SPA's that need to work regardless of hosting environment, using hash-based navigation is usually the best solution, especially if link-sharing is integral to the app.

    I made these small changes to enable hash support:

    if ((uri = fmt(uri || location.href.replace(location.origin, "")))) {
    //uri = uri.match(/[^\?#]*/)[0];
    

    and

    ...
    		addEventListener("click", click);
    		addEventListener("hashChange", run);
    		$.unlisten = function() {
    ...
    			removeEventListener("click", click);
    			removeEventListener("hashChange", run);
    		};
    

    Given the regex I assume you did not want support for hashes in this library, but happy to write a test and submit a pull if you are open to it.

    opened by TJKoury 7
  • 404 flashes on page refresh

    404 flashes on page refresh

    Hi @lukeed thanks for your work on this router! I'm having some trouble with 404 page not found handling and was wondering if you could point me in the right direction. Whenever I do a Ctrl+r to reload the page I see the 404 page flicker before loading the correct page (sometimes it doesn't reach the correct page and just loads the 404). Here are some project details in case it's helpful:

    • I have static HTML fallbacks for each page that hydrate into svelte components
    • The static HTML paths are in the format /about/index.html so I match the urls with trailing slashes and redirect them to the same page but without the slash in the spa (e.g. /about)
    • I dynamically create the routes using a data source (nodes.js)
    Click to see router code
    <Html {route} {node} {allNodes} />
    
    <script>
      import Navaid from 'navaid';
      import nodes from './nodes.js';
      import Html from '../global/html.svelte';
    
      let route, node, allNodes;
    
      const getNode = (uri, trailingSlash = "") => {
        return nodes.find(node => node.path + trailingSlash == uri);
      }
    
      let uri = location.pathname;
      node = getNode(uri);
      if (node === undefined) {
        node = getNode(uri, "/");
      }
      allNodes = nodes;
    
      function draw(m) {
        node = getNode(uri);
        if (node === undefined) {
          // Create a placeholder node so props are complete
          node = {
            "path": "/404",
            "type": "404",
            "filename": "404.json",
            "fields": {}
          }
        }
        route = m.default;
        window.scrollTo(0, 0);
      }
    
      function track(obj) {
        uri = obj.state || obj.uri;
      }
    
      addEventListener('replacestate', track);
      addEventListener('pushstate', track);
      addEventListener('popstate', track);
    
      const router = Navaid('/', () => import('../content/404.js').then(draw));
    
      allNodes.forEach(node => {
        router.on(node.path, () => {
          // Check if the url visited ends in a trailing slash (besides the homepage).
          if (uri.length > 1 && uri.slice(-1) == "/") {
            // Redirect to the same path without the trailing slash.
            router.route(node.path, false);
          } else {
            import('../content/' + node.type + '.js').then(draw);
          }
        }).listen();
    
      });
    
    </script>
    

    Thanks!

    opened by jimafisk 5
  • Allow for state params in pushState

    Allow for state params in pushState

    Starting to use your library with Svelte 3. This is either a question or feature request...

    I see the pushState events are basically using the state param for the uri. This removes ability to history.pushState(someRouteState, ...) right?

    Seems like it would be nice to have pushState state param, say, default to null but be available to use.... when caching some route data like here:

    https://twitter.com/ryanflorence/status/1111272046372093953

    None of the other generic routers seem to handle this well OR they don't handle search params well or something. Yours is best so far and small. But having state available would be nice.

    opened by cdock1029 5
  • Show loading before load and hide after load

    Show loading before load and hide after load

    Hi,

    How i can receive a generic event before load component and after load it?

    My components .js file are loaded dynamically, so it still on home until the .js file is loaded. So i want show a loading toast and hide after it was loaded.

    const router = Navaid("/")
            .on("/", () => run(import("../routes/Home.svelte")))
            .on("/about", () => run(import("../routes/About.svelte")))
    

    Can you help me?

    Thanks.

    opened by paulocoutinhox 4
  • [RFC] Prevent routing to current path

    [RFC] Prevent routing to current path

    Assuming this setup:

    router = (
      navaid()
        .on('/', () => console.log('doing something'))
        .listen()
    );
    

    You will be doing something every time the "/" path is routed. This is common sense & to be expected. However, what might not be obvious is that if you have a standard link in a global component (eg, a navbar) pointing to the home page:

    <a href="/">Go Home</a>
    

    ... and click it repeatedly, you will be doing something for each of those clicks, even though you're already on the "/" route.


    This is posted as a RFC because it might qualify as a breaking change in some apps.
    Many might actually be relying on this behavior to reset page state, for example.

    Please let me know below :)

    feedback wanted 
    opened by lukeed 4
  • RFC: Multiple Navaid Instances?

    RFC: Multiple Navaid Instances?

    There's currently not a good way to handle multiple routers within the same page. But what are your thoughts about this for handling multiple routers in a page?

    TBH I'm not even sure that this is a good idea... still on the fence

    var items = (
      navaid()
        .on('/items/', () => console.log('Items Home'))
        .on('/items/:title', x => console.log('Item: ', x.title))
    );
    
    var books = (
      navaid()
        .on('/books/', () => console.log('Books Home'))
        .on('/books/:title', x => console.log('Book: ', x.title))
    );
    
    var main = (
      navaid()
        .on('/', () => console.log('Home'))
        .on('/about', () => console.log('About'))
        .use(items)
        .use(books)
        .on('/contact', () => console.log('Contact'))
    );
    
    main.listen();
    

    I already have this built, and it seems to be the only sane way to juggle multiple routers on a page.

    As for actual routing, there are two options:

    1. Look at the main routes first and then the sub-routers' routes, disregarding the order of the router composition:

      /   –>   /about   –>   /contact   –>   /items   –>   /items/:title   –>   /books   –>   /books/:title
      
    2. Treat all routers' routes equally, respecting the order of composition:

      /   –>   /about   –>   /items   –>   /items/:title   –>   /books   –>   /books/:title   –>   /contact
      

    Of course, another alternative is to do something like this:

    main.listen();
    items.listen();
    books.listen();
    

    ...which feels much simpler to the end-user, but it very likely adds a considerable amount of overhead to Navaid in order to facilitate that. IMO it may not be worth it, especially if/when the 90% use-case is to use a single instance per App.


    No matter the choice, handling the on404 behavior needs answering, too. For example, if main, items, and books all have their own 404-handler, how will one know to fire vs wait for a sibling router? Similarly, what if only books had a 404-handler defined... how should it know that it's okay to run?

    My hunch is that the 2nd option (3x .listen()) is not compatible with this at all.

    feedback wanted 
    opened by lukeed 4
  • fix HTMLAnchorElement download attr behavior

    fix HTMLAnchorElement download attr behavior

    Hello mate

    Quick fix to make my project work. Please feel free to update this PR.

    https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement/download

    opened by k1r0s 0
  • How to add go back action?

    How to add go back action?

    I would like to add an in-app back button that should go back in the history, but if it would leave my site it should call history.replaceState to a fallback instead.

    For example, if I click on a link to example.com/products/123, the in-app back button would work as router.route('/products', true), but if I was already at any page in that site and navigated to that route, the button would work as history.back().

    The falback uri would be different depending on the page and should be specified, but it could default to /.

    opened by aryelgois 8
  • Hosting requirements

    Hosting requirements

    Hello!

    All we know that example: https://codesandbox.io/s/reverent-tesla-c0kq0 But when you update sirv-cli from 0.3.1 to last version 1.0.8 you will get strange behavior. All svelte project become rerendering multiple times and it will be difficult to call it SPA as for me. You should see console after changing sirv-cli version. For example: 1 click to "Go to Teams Page" and you will get 9 same messages "~> App is drawing ::
    PageTeamList ".

    I will go with other serving software in production and it could be no problem but i am not sure.

    What is the problem here? And how i could fix it? And how i could name that problem correctly?

    Thank you!

    opened by Renboo 0
  • before / after handlers

    before / after handlers

    I see there's on. It's not clear to me from the docs whether that happens before or after, but it'd be cool if there were also a handler for the other one

    This is low priority for me since I'm not actually using navaid for anything right now. Just something I noticed was missing from the API and thought I'd share as a suggestion

    opened by benmccann 0
  • Support for cancelling navigation?

    Support for cancelling navigation?

    Hi, Is it possible to cancel navigation in navaid? In an editor scenario I would like to setup a dirty flag so that if the user wants to navigate off the page while the editor has changes, to prompt the user and give him the chance to cancel navigation.

    In the svelte-demo repo I have seen a good example of route guards for the protected/admin area scenario. Following that sample code, I could conditionally prompt the user based on a dirty flag and do nothing at all if he or she chooses to cancel. But from navaids point of view, the navigation would have already happened and the history would reflect the new url.

    I thinks a beforeNavigation hook would be a great addition to the the library.

    Is it possible to solve this scenario in navaids current incarnation?

    Thanks!!

    const router = (
      Navaid('/')
      // support for cancelling navigation??
      .beforeNavigation((newPath, oldPath) => {
        if($dirtyFlag) {
          // prompt user  
          // return false to cancel navigation      
          return false;
        }
        return true;
      })
      .on('/', () => run(import('../routes/Home.svelte')))
      .on('/about', () => run(import('../routes/About.svelte')))
      .on('/login', () => run(import('../routes/Login.svelte')))
      .on('/private', () => onAdmin(import('../routes/Private.svelte')))
      .on('/forbidden', () => run(import('../routes/Forbidden.svelte')))
      .on('/blog', () => run(import('../routes/Blog.svelte')))
      .on('/blog/:postid', obj => run(import('../routes/Article.svelte'), obj))
      );
    function onAdmin(thunk, obj) {
      if ($isAdmin) return run(thunk, obj);
      if ($isUser) return router.route('/forbidden', true);
      router.route('/login', true);
    }
    
    opened by germanftorres 2
  • Support for shadow dom

    Support for shadow dom

    Intercepting clicks made on anchors inside shadow roots looking for the anchor closest to the event target doesn't work since events are re-targeted to the shadow root host element.

    The anchor can be found in the event path with the following code:

    function findA(e){
      var i = 0, p = e.path || e.composedPath && e.composedPath(), a = p && p[i];
      while(a && a.tagName !== 'A') a = p[++i];
      return a;
    }
    

    Note that this will only work for shadow roots configured with mode set to open since elements inside closed ones don't appear in the event path.

    Can submit a PR if you agree with the proposed change

    feedback wanted 
    opened by isidrok 5
Releases(v1.2.0)
  • v1.2.0(Oct 6, 2020)

  • v1.0.4(Jun 3, 2019)

    Patches

    • Prevent memory leak from multiple wrap calls (#8): 0f5b5bb
    • Ignore query string (location.search) during $.run call: (#9): 1062d25

    Chores

    • (Golf) Remove off variable for larger gzip reuse: 77fa92d
    • (Golf) Write fn handlers directly into route objects: 11a5f29
    • (Test) Assert $.run ignores query string values (#9): e7aa014
    • (Docs) Update size: fda2f4e
    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Apr 25, 2019)

  • v1.0.1(Apr 25, 2019)

    Features

    • With the latest version of regexparam, Navaid can now support suffix matches

       // Examples from "regexparam"
      // All patterns are now valid within Navaid~!
      
       let now = regexparam('/movies/:title.(mp4|mov)');
      
       exec('/movies/narnia.mp4', now);
       //=> { title: 'narnia' }
      
       exec('/movies/narnia.mov', now);
       //=> { title: 'narnia' }
      
       exec('/movies/narnia.wav', now);
       //=> {}  (no match)
      

    Patches

    • Ignore/Release links to different host targets (#3): b4561f9
    • Refactor: Ignore unnecessary looping inside $.run: f1291ad
    • Gold: Shave 7 bytes: 618cd53

    Chores

    • Update sizes: f161f76, 7060350
    • Update tooling: 64da2b0, dd9ce06
    Source code(tar.gz)
    Source code(zip)
Owner
Luke Edwards
Luke Edwards
A chainable router designed for Next.js api. inspired and regex based from itty-router

Next.js Api Router A chainable router designed for Next.js api. inspired and regex based from itty-router Features Tiny (~8xx bytes compressed) with z

Aris Riswanto 1 Jan 21, 2022
a tiny and isomorphic URL router for JavaScript

Synopsis Director is a router. Routing is the process of determining what code to run when a URL is requested. Motivation A routing library that works

a decoupled application framework 5.6k Dec 28, 2022
An Express.js-Style router for the front-end

An Express.js-Style router for the front-end. Code the front-end like the back-end. Same language same framework. frontexpress demo import frontexpres

Camel Aissani 262 Jul 11, 2022
⚡️The Fullstack React Framework — built on Next.js

The Fullstack React Framework "Zero-API" Data Layer — Built on Next.js — Inspired by Ruby on Rails Read the Documentation “Zero-API” data layer lets y

⚡️Blitz 12.5k Jan 4, 2023
Crowdsourcing aid data across the nation

The Sambal SOS App Formerly the Bendera Putih App Table of Contents The #benderaputih Movement Usage About us Contributing Prerequisites How to Instal

Sidharrth Nagappan 28 Oct 3, 2022
A lightweight (~850 B) library for easy mac/window shortcut notation. kbd-txt convert shortcut text depending on the type of OS (window/linux/mac).

kbd-txt A lightweight (~850 B) library for easy mac/window shortcut notation. kbd-txt convert shortcut text depending on the type of OS (window/linux/

Minung Han 6 Jan 1, 2023
Navigation-Menu-Javascript - A simple Navbar navigation using vanilla javascript, to change links to the active link when clicked.

Navigation-Menu-Javascript A simple Navbar navigation using vanilla javascript, to change links to the active link when clicked. Desktop view Mobile v

Ellis 2 Feb 16, 2021
Micro client-side router inspired by the Express router

Tiny Express-inspired client-side router. page('/', index) page('/user/:user', show) page('/user/:user/edit', edit) page('/user/:user/album', album) p

Sloth 7.6k Dec 28, 2022
A chainable router designed for Next.js api. inspired and regex based from itty-router

Next.js Api Router A chainable router designed for Next.js api. inspired and regex based from itty-router Features Tiny (~8xx bytes compressed) with z

Aris Riswanto 1 Jan 21, 2022
Router JS 💽 Simple Router building in JavaScript

Router JS ?? Simple Router building in JavaScript

David Montaño Tamayo 1 Feb 12, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
New tab browser extension (aka startpage) with nord colors and a dancing goose.

Nordic goose Nordic goose is a new tab extension (aka startpage) with nord colors and a dancing goose. Features: ?? Look at a dancing goose ?? Beautif

PrettyCoffee 9 Dec 30, 2022
A tiny javascript templating framework in ~400 bytes gzipped

t.js A tiny javascript templating framework in ~400 bytes gzipped t.js is a simple solution to interpolating values in an html string for insertion in

Jason Mooberry 823 Dec 29, 2022
A general purpose internationalization library in 292 bytes

A general purpose internationalization library in 298 bytes! Features Simple and Familiar API Unobstrusive and Unopinionated Less than 300 bytes – inc

Luke Edwards 713 Dec 21, 2022
2 player tictactoe-hosting TCP server in 640 bytes

tictactinytoe 2 player tictactoe-hosting TCP server in 640 bytes: F=_=>{x=o=z=0;t=1};F();require("net").createServer(c=>{h="\n";w=s=>c.write(s+h);if(o

Shivam Mamgain 25 Jul 27, 2022
A tiny (108 bytes), secure, URL-friendly, unique string ID generator for JavaScript

Nano ID English | Русский | 简体中文 | Bahasa Indonesia A tiny, secure, URL-friendly, unique string ID generator for JavaScript. “An amazing level of sens

Andrey Sitnik 19.6k Jan 8, 2023
World's smallest responsive 🔥 css framework (395 bytes)

lit ?? a ridiculously small responsive css framework. I challenged myself to see how small I could go, but preserve everything Skeleton, Milligram, an

Arham Jain 1.9k Jan 7, 2023
A POC of a Discord.js bot that sends 3D rendering instructions to a Go server through gRPC which responds with the image bytes which are then sent back on Discord.

A POC of a Discord.js bot that sends 3D rendering instructions to a Go server through gRPC which responds with the image bytes which are then sent back on Discord.

Henrique Corrêa 5 Jan 8, 2022