A faster alternative to legacy node:querystring module

Overview

fast-querystring

Test codecov NPM version

Fast query-string parser and stringifier to replace the legacy node:querystring module.

Installation

npm i fast-querystring

Features

  • Supports both parse and stringify methods from node:querystring module
  • Parsed object does not have prototype methods
  • Uses & separator as default
  • Supports only input of type string
  • Supports repeating keys in query string
    • foo=bar&foo=baz parses into {foo: ['bar', 'baz']}
  • Supports pairs with missing values
    • foo=bar&hola parses into {foo: 'bar', hola: ''}
  • Stringify does not support nested values (just like node:querystring)

Usage

const qs = require('fast-querystring')

// Parsing a querystring
console.log(qs.parse('hello=world&foo=bar&values=v1&values=v2'))
// {
//   hello: 'world',
//   foo: 'bar',
//   values: ['v1', 'v2']
// }

// Stringifying an object
console.log(qs.stringify({ foo: ['bar', 'baz'] }))
// 'foo=bar&foo=baz'

Benchmark

  • Parsing a query-string
> node benchmark/parse.mjs

╔═════════════════════════════════════════╤═════════╤═══════════════════╤═══════════╗
║ Slower tests                            │ Samples │            Result │ Tolerance ║
╟─────────────────────────────────────────┼─────────┼───────────────────┼───────────╢
║ qs                                      │   10000 │  310825.09 op/sec │  ± 1.29 % ║
║ query-string                            │    1000 │  340059.83 op/sec │  ± 0.82 % ║
║ querystringify                          │   10000 │  435456.34 op/sec │  ± 1.06 % ║
║ @aws-sdk/querystring-parser             │    1000 │  451618.35 op/sec │  ± 0.85 % ║
║ URLSearchParams-with-Object.fromEntries │   10000 │  876030.86 op/sec │  ± 1.78 % ║
║ URLSearchParams-with-construct          │   10000 │ 1239366.24 op/sec │  ± 2.59 % ║
║ node:querystring                        │   10000 │ 1442731.43 op/sec │  ± 2.95 % ║
║ querystringparser                       │    3000 │ 1863385.29 op/sec │  ± 0.99 % ║
╟─────────────────────────────────────────┼─────────┼───────────────────┼───────────╢
║ Fastest test                            │ Samples │            Result │ Tolerance ║
╟─────────────────────────────────────────┼─────────┼───────────────────┼───────────╢
║ fast-querystring                        │   10000 │ 2086260.18 op/sec │  ± 3.18 % ║
╚═════════════════════════════════════════╧═════════╧═══════════════════╧═══════════╝
  • Stringify a query-string
> node benchmark/stringify.mjs

╔══════════════════════════════╤═════════╤═══════════════════╤═══════════╗
║ Slower tests                 │ Samples │            Result │ Tolerance ║
╟──────────────────────────────┼─────────┼───────────────────┼───────────╢
║ query-string                 │   10000 │  294354.42 op/sec │  ± 1.25 % ║
║ qs                           │   10000 │  349992.31 op/sec │  ± 1.45 % ║
║ @aws-sdk/querystring-builder │   10000 │  380426.03 op/sec │  ± 1.69 % ║
║ http-querystring-stringify   │   10000 │  489248.93 op/sec │  ± 1.54 % ║
║ URLSearchParams              │   10000 │  579241.21 op/sec │  ± 1.92 % ║
║ querystringparser            │    1500 │  667303.72 op/sec │  ± 0.77 % ║
║ querystringify               │   10000 │  780283.61 op/sec │  ± 2.43 % ║
║ node:querystring             │   10000 │ 1779241.34 op/sec │  ± 6.49 % ║
╟──────────────────────────────┼─────────┼───────────────────┼───────────╢
║ Fastest test                 │ Samples │            Result │ Tolerance ║
╟──────────────────────────────┼─────────┼───────────────────┼───────────╢
║ fast-querystring             │   10000 │ 2125769.45 op/sec │  ± 3.93 % ║
╚══════════════════════════════╧═════════╧═══════════════════╧═══════════╝
Comments
  • perf: 15 % better perf for number to string, avoid intermediate Math.abs, use implicit number to string coercion

    perf: 15 % better perf for number to string, avoid intermediate Math.abs, use implicit number to string coercion

    The reason why we do Math.abs is because 1e21.toString() returns "1e+21". + gets encoded but - not. So there is no good reason to do a Math.abs call. We only need to know if the number is bigger or equal than 1e21.

    We could probably optimize also the >= 1e21 case because we only need to replace the +. But I guess that case is actually neglectable, because we are already bigger than Number.MAX_SAFE_INTEGER.

    My benchmarks showed that doing

    const tmp = value.toString(); 
    const pos = tmp.indexOf('+'); 
    return value.slice(0, pos) + '%2B' + value.slice(pos + 1);
    

    could be faster than calling encodeString.

    opened by Uzlopak 7
  • perf: add benchmarks for importing all packages

    perf: add benchmarks for importing all packages

    Related to https://github.com/nodejs/undici/pull/1679

    ➜  fast-querystring git:(perf/benchmark) npm run benchmark:import
    
    > [email protected] benchmark:import
    > node benchmark/import.mjs
    
    ╔═════════════════════════════╤═════════╤══════════════════╤═══════════╗
    ║ Slower tests                │ Samples │           Result │ Tolerance ║
    ╟─────────────────────────────┼─────────┼──────────────────┼───────────╢
    ║ @aws-sdk/querystring-parser │    1000 │  10219.42 op/sec │  ± 0.47 % ║
    ║ querystringparser           │    1000 │  10733.12 op/sec │  ± 0.47 % ║
    ║ query-string                │    1000 │  11056.24 op/sec │  ± 0.47 % ║
    ║ qs                          │    1000 │  11117.31 op/sec │  ± 0.49 % ║
    ║ querystringify              │    1000 │  11737.47 op/sec │  ± 0.49 % ║
    ║ fast-querystring            │    1500 │  37799.39 op/sec │  ± 0.86 % ║
    ╟─────────────────────────────┼─────────┼──────────────────┼───────────╢
    ║ Fastest test                │ Samples │           Result │ Tolerance ║
    ╟─────────────────────────────┼─────────┼──────────────────┼───────────╢
    ║ node:querystring            │   10000 │ 228785.04 op/sec │  ± 1.19 % ║
    ╚═════════════════════════════╧═════════╧══════════════════╧═══════════╝
    
    opened by anonrig 4
  • avoid deoptimization

    avoid deoptimization

    deoptigate reports an out of bounds error resulting in a eager bailout. My benchmarks are on node 18.

    My benchmark:

    'use strict'
    
    const Benchmark = require('benchmark');
    const fastQueryString = require("./lib/index.js");
    var suite = new Benchmark.Suite;
    
    suite.add('fastQueryString', function() {
      fastQueryString.parse("hello=world&foo=bar&foo=baz")
    })
    // add listeners
    .on('cycle', function(event) {
      console.log(String(event.target));
    })
    .on('complete', function() {
      console.log('Fastest is ' + this.filter('fastest').map('name'));
    })
    .run();
    

    before:

    fastQueryString x 3,002,304 ops/sec ±0.48% (94 runs sampled)
    Fastest is fastQueryString
    

    after:

    fastQueryString x 3,661,458 ops/sec ±0.76% (94 runs sampled)
    Fastest is fastQueryString
    
    opened by Uzlopak 2
  • some optimizations?

    some optimizations?

    @anonrig

    https://github.com/anonrig/fast-querystring/blob/212c51ce68c4109de4ba1c798bd8008ed17cce9e/lib/parse.js#L44-L45

    .replaceAll('+', ' ') is probably faster than the regex variant.

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll

    https://github.com/anonrig/fast-querystring/blob/212c51ce68c4109de4ba1c798bd8008ed17cce9e/lib/parse.js#L27

    Number.isNaN() is more robust

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN

    opened by leeoniya 2
  • build(deps-dev): bump query-string from 7.1.3 to 8.1.0

    build(deps-dev): bump query-string from 7.1.3 to 8.1.0

    Bumps query-string from 7.1.3 to 8.1.0.

    Release notes

    Sourced from query-string's releases.

    v8.1.0

    • Upgrade dependencies (#365) 20cc109

    https://github.com/sindresorhus/query-string/compare/v8.0.3...v8.1.0

    v8.0.3

    • Fix typo in a TypeScript type 7bba5bb

    https://github.com/sindresorhus/query-string/compare/v8.0.2...v8.0.3

    v8.0.2

    • Improve compatibility with bundlers (#361) 81f78e6

    https://github.com/sindresorhus/query-string/compare/v8.0.1...v8.0.2

    v8.0.1

    • Fix TypeScript compatibility 76f8fc5

    https://github.com/sindresorhus/query-string/compare/v8.0.0...v8.0.1

    v8.0.0

    Breaking

    Fixes

    • Fix encoding of fragmentIdentifier (#355) 16a7b8f

    https://github.com/sindresorhus/query-string/compare/v7.1.3...v8.0.0

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies javascript 
    opened by dependabot[bot] 1
  • build(deps-dev): bump @vitest/coverage-c8 from 0.23.4 to 0.26.3

    build(deps-dev): bump @vitest/coverage-c8 from 0.23.4 to 0.26.3

    Bumps @vitest/coverage-c8 from 0.23.4 to 0.26.3.

    Release notes

    Sourced from @​vitest/coverage-c8's releases.

    v0.26.3

       🚀 Features

       🐞 Bug Fixes

        View changes on GitHub

    v0.26.2

       🚀 Features

       🐞 Bug Fixes

        View changes on GitHub

    v0.26.1

       🚀 Features

       🐞 Bug Fixes

        View changes on GitHub

    v0.26.0

       🚨 Breaking Changes

    • vite-node: Rewrite how vite-node resolves id  -  by @​sheremet-va in vitest-dev/vitest#2463 (58ee8)
    • Correctly interop nested default for external and inlined modules  -  by @​sheremet-va in vitest-dev/vitest#2512 (084e9)
      • If your environment is node, Vitest will not resolve invalid named exports (exports that are on "default" property will not magically appear as named exports), unless deps.interopDefault is enabled, or dependency is in deps.inline. This change doesn't affect jsdom, happy-dom or edge environments.
    • web-worker: Make web-worker implementation more compatible with spec  -  by @​sheremet-va in vitest-dev/vitest#2431 (c3a63)
      • Messages are now cloned with structuredClone, if it's available, or fallbacks to a polyfill.
      • Added support for SharedWorker

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies javascript 
    opened by dependabot[bot] 1
  • build(deps-dev): bump vitest from 0.23.4 to 0.26.3

    build(deps-dev): bump vitest from 0.23.4 to 0.26.3

    ⚠️ Dependabot is rebasing this PR ⚠️

    Rebasing might not happen immediately, so don't worry if this takes some time.

    Note: if you make any changes to this PR yourself, they will take precedence over the rebase.


    Bumps vitest from 0.23.4 to 0.26.3.

    Release notes

    Sourced from vitest's releases.

    v0.26.3

       🚀 Features

       🐞 Bug Fixes

        View changes on GitHub

    v0.26.2

       🚀 Features

       🐞 Bug Fixes

        View changes on GitHub

    v0.26.1

       🚀 Features

       🐞 Bug Fixes

        View changes on GitHub

    v0.26.0

       🚨 Breaking Changes

    • vite-node: Rewrite how vite-node resolves id  -  by @​sheremet-va in vitest-dev/vitest#2463 (58ee8)
    • Correctly interop nested default for external and inlined modules  -  by @​sheremet-va in vitest-dev/vitest#2512 (084e9)
      • If your environment is node, Vitest will not resolve invalid named exports (exports that are on "default" property will not magically appear as named exports), unless deps.interopDefault is enabled, or dependency is in deps.inline. This change doesn't affect jsdom, happy-dom or edge environments.
    • web-worker: Make web-worker implementation more compatible with spec  -  by @​sheremet-va in vitest-dev/vitest#2431 (c3a63)
      • Messages are now cloned with structuredClone, if it's available, or fallbacks to a polyfill.
      • Added support for SharedWorker

    ... (truncated)

    Commits
    • 8d64790 chore: release v0.26.3
    • dba1337 fix(coverage): env-replacer to remove query params from sourcemaps filenames ...
    • 32a577b fix: show list of tests when typechecking (#2585)
    • c479d9c fix: don't hang when mocking module with circular dependency (#2572)
    • 9f41edd fix: start tracking module resolution as soon as possible for easier tracking...
    • ef77dcc fix(api): make api parse error stacks and return sourcePos in onTaskUpdate (#...
    • 853eedd feat(mock): expose a importOriginal helper to the factory (#2551)
    • 07ef0f2 chore: release v0.26.2
    • f6b592a fix(cli): respect inline config dir (#2550)
    • 84f98e7 feat: project name
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies javascript 
    opened by dependabot[bot] 1
  • add fine grained benchmarks

    add fine grained benchmarks

    This PR adds fine grained benchmarks. We can then even compare branches and decide if the overall performance improves or not.

    Based on the benchmarks in fast-json-stringify.

    opened by Uzlopak 1
  • Add supporting metadata to benchmarks

    Add supporting metadata to benchmarks

    Would be beneficial for the benchmark table to have supporting information such as:

    • Specs of the machine running the benchmarks
    • Node version
    • Run date and time

    Similar to https://github.com/fastify/benchmarks#benchmarks

    This would allow viewers to know how current/accurate the benchmarks are.

    opened by Fdawgs 1
  • ci: update workflow

    ci: update workflow

    This PR:

    • Removes Git credentials/SSH keys after checkout as a security precaution by setting persist-credentials to false, they are not used after the initial checkout
    • Adds --ignore-scripts option to pnpm install command to protect against malicious scripts in dependencies
    • Enables concurrency in ci.yml; see related docs, this allows a subsequently queued workflow run to interrupt previous runs in PRs
    opened by Fdawgs 1
  • use -1 instead of 0 as lastIndex indicator

    use -1 instead of 0 as lastIndex indicator

    this is a follow up to #2

    I thought about it. Probably somebody is crazy enough to use %00 in his/her query and then it would stop parsing to early.

    Performance seems to be still the same.

    opened by Uzlopak 1
Releases(1.0.0)
  • 1.0.0(Sep 13, 2022)

    fast-querystring is now 45% faster than node:querystring module

    What's Changed

    • perf: improve equality detection and reuse it by @anonrig in https://github.com/anonrig/fast-querystring/pull/21
    • chore: release 1.0.0 by @anonrig in https://github.com/anonrig/fast-querystring/pull/22

    Full Changelog: https://github.com/anonrig/fast-querystring/compare/0.7.1...1.0.0

    Source code(tar.gz)
    Source code(zip)
  • 0.7.1(Sep 9, 2022)

    What's Changed

    • build: start testing parser in a wide range of versions by @anonrig in https://github.com/anonrig/fast-querystring/pull/16
    • test: add code coverage by @anonrig in https://github.com/anonrig/fast-querystring/pull/17
    • docs: add badges to readme by @anonrig in https://github.com/anonrig/fast-querystring/pull/19
    • test: add multi-byte tests to stringify by @anonrig in https://github.com/anonrig/fast-querystring/pull/20

    Full Changelog: https://github.com/anonrig/fast-querystring/compare/0.7.0...0.7.1

    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Sep 8, 2022)

    fast-querystring is now 40% faster than node:querystring module

    What's Changed

    • chore(.npmignore): remove LICENSE by @Fdawgs in https://github.com/anonrig/fast-querystring/pull/14
    • perf: improve parse performance by 12% by @anonrig in https://github.com/anonrig/fast-querystring/pull/15

    Full Changelog: https://github.com/anonrig/fast-querystring/compare/0.6.1...0.7.0

    Source code(tar.gz)
    Source code(zip)
  • 0.6.1(Sep 6, 2022)

  • 0.6.0(Sep 6, 2022)

    What's Changed

    • avoid deoptimization by @Uzlopak in https://github.com/anonrig/fast-querystring/pull/4
    • use -1 instead of 0 as lastIndex indicator by @Uzlopak in https://github.com/anonrig/fast-querystring/pull/7
    • fix: remove unnecessary check by @anonrig in https://github.com/anonrig/fast-querystring/pull/6
    • perf: use fast-decode-uri-component for decoding by @anonrig in https://github.com/anonrig/fast-querystring/pull/8
    • perf: use replaceAll instead of replacing plus by @anonrig in https://github.com/anonrig/fast-querystring/pull/9
    • ci: update workflow by @Fdawgs in https://github.com/anonrig/fast-querystring/pull/12
    • docs(readme): remove legacy npm arg by @Fdawgs in https://github.com/anonrig/fast-querystring/pull/13
    • feat: add querystring stringify by @anonrig in https://github.com/anonrig/fast-querystring/pull/11

    New Contributors

    • @Uzlopak made their first contribution in https://github.com/anonrig/fast-querystring/pull/4
    • @anonrig made their first contribution in https://github.com/anonrig/fast-querystring/pull/6
    • @Fdawgs made their first contribution in https://github.com/anonrig/fast-querystring/pull/12

    Full Changelog: https://github.com/anonrig/fast-querystring/commits/0.6.0

    Source code(tar.gz)
    Source code(zip)
An all new Titanfall VPK unpacker. Over 2x faster than the most popular alternative!

Harmony VPK Tool An electron-based app for unpacking Respawn VPK files. Super-fast and made with ♥ Why use Harmony VPK Tool over cra0's VPKTool? It's

Harmony 16 Dec 19, 2022
An npm package for demonstration purposes using TypeScript to build for both the ECMAScript Module format (i.e. ESM or ES Module) and CommonJS Module format. It can be used in Node.js and browser applications.

An npm package for demonstration purposes using TypeScript to build for both the ECMAScript Module format (i.e. ESM or ES Module) and CommonJS Module format. It can be used in Node.js and browser applications.

Snyk Labs 57 Dec 28, 2022
A JavaScript module that shortens your code, makes life easier, and makes development faster!

Quxt A JavaScript module that shortens your code, makes life easier, and makes development faster! Installation npm install quxt Quick Start Check ind

Qux App 5 May 8, 2022
An non-official esx-legacy 1.5 version for quasar inventory purpose.

Hi there ! It's my first post on github, and I'm releasing a free edited base with esx-legacy 1.5 compatible and made for Quasar Inventory. How can I

ChernyyOrel 3 Mar 19, 2022
Several custom made and legacy icons, and icons collected all over the internet in 1 set, UI selectable.

Custom icon library Several custom made and legacy icons, and icons collected all over the internet in 1 set, UI selectable. Upon each Material Design

Marius 12 Dec 12, 2022
This script is the defacto way to enable use of HTML5 sectioning elements in legacy Internet Explorer.

The HTML5 Shiv The HTML5 Shiv enables use of HTML5 sectioning elements in legacy Internet Explorer and provides basic HTML5 styling for Internet Explo

Alexander Farkas 9.9k Jan 2, 2023
radiQL, your one-stop-shop for migrating from a legacy REST backend to an efficient and modern GraphQL API

Welcome to radiQL, the one-stop solution for setting up GraphQL on a PostgreSQL database. Check out our Medium article here. At A Glance: Give us your

OSLabs Beta 90 Nov 14, 2022
A Proxy based alternative to json-watch module.

@webreflection/json-watch Social Media Photo by Andrik Langfield on Unsplash A modern take at this 7yo json-watch module. import watcher from '@webref

Andrea Giammarchi 12 Sep 9, 2022
Userland module that implements the module path mapping that Node.js does with "exports" in package.json

exports-map Userland module that implements the module path mapping that Node.js does with "exports" in package.json npm install exports-map Usage co

Mathias Buus 9 May 31, 2022
Node 18's node:test, as a node module

node-core-test This is a user-land port of node:test, the experimental test runner introduced in Node.js 18. This module makes it available in Node.js

Julian Gruber 62 Dec 15, 2022
Fintoc.js ES Module - Use the Fintoc widget as an ES module

Fintoc.js ES Module Use the Fintoc widget as an ES module. Installation Install using npm! (or your favourite package manager) # Using npm npm install

Fintoc 6 May 13, 2022
Template Repository for making your own budder Module. CORE is not included, this is just for the module.

A quick copy of the "How to make your own module" section Check out the official budderAPI repository Template Repository for making your own budder M

Logic 2 Apr 3, 2022
A module federation SDK which is unrelated to tool chain for module consumer.

hel-micro, 模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 Demo hel-loadash codesandbox hel-loadash git Why hel-micro 如何使用远程模块 仅需要一句npm命令即可载入远程模块,查看下面例子线上示例 1 安装hel-micr

腾讯TNTWeb前端团队 319 Jan 3, 2023
GetOsLocalesCrossPlatform - A cross platform alternative to get locales used on the platform. Works on Node, Electron, NW.js and Browsers

getOsLocalesCrossPlatform A cross platform alternative to get locales used on the platform. Works on Node, Electron, NW.js and Browsers This script is

null 1 Jan 2, 2022
🎮 The only Front-End Performance Checklist that runs faster than the others

Front-End Performance Checklist ?? The only Front-End Performance Checklist that runs faster than the others. One simple rule: "Design and code with p

David Dias 15.5k Jan 1, 2023
2x times faster than chalk and use 5x less space in node_modules

Nano Colors A tiny and fast Node.js library for formatting terminal text with ANSI colors. It is 2 times faster than chalk. Both loading and calls. No

Andrey Sitnik 886 Dec 30, 2022
Debug express.js server code with Ray to fix problems faster

express-ray Install this package in any Express.js project to provide an exceptional debugging experience using the Ray app by Spatie. Installation In

Permafrost Software 8 Nov 3, 2022
Cloudy is a set of constructs for the AWS Cloud Development Kit that aim to improve the DX by providing a faster and type-safe code environment.

cloudy-ts These packages aren't yet published on npm. This is still highly experimental. Need to figure out a few things before releasing the first ve

Cristian Pallarés 5 Nov 3, 2022