Zero-dependency CLIs with Node.js

The contents here is created from the official CascadiaJS Page

Overview

Ian Sutherland image

Abstract

Node.js is a popular choice for building dev tools and some recently added features make it possible to build powerful tools without any external dependencies. We’ll look at these new features and show how to use them to build a custom CLI app with zero external dependencies.

Notes

Notes by aminamos

  • Neo Financial, Head of DEX and OSS
  • twitter @iansu (Private)
  • flags
    • -l1 or -l -1 Short options
    • --color Long options
  • subcommands
    • the status in git status
  • "CLI is serious 80s vibes"
  • Node has a small core which is why there are lots of dependencies installed with npm for a given project like isNumber.
  • Bundling isn't the best because it can still result in a large bundle size.
  • type: module to package.json to use import and ESMM or us .mjs (as opposed to .cjs).
  • import Node.js internals with node:
    • eg, import fs from 'node:fs'
  • There are many different ways to set arguments in a cli
  • parseArgs: process.argv -> Tedious so use yargs of commander.
    • NOT TEDIOUS ANYMORE! parseArgs from 'node:util' uses process.argsv
      • declare the options (kind of like commander)
    • has polyfill, will be "backboarded" to v16
  • fetch: now available in node@18
    • Built on top of Undici (HTTP/1.1)
  • see iansu/git-blast on github to run git blast and see people's twitter handle's if supplied on githu
  • node@18 now has a basic test runner.
    • don't necessarily need jest anymore.
    • node --test
  • recursive mkdir function with {recursive: true}
  • recursive rm operation {recursive: true, force: true}
  • recursive cp (same as mkdir) **experimental
  • readdir **open pr, not merged
  • Speculation of what's next
    • glob patterns
    • self contained executables
    • native typescript (aka deno)

build the future

Notes by kevin

  • cli apps

    • stuff that runs on the terminal
  • features

    • options (eg. ls)
    • subcommands (eg. git)
  • why node

    • scripting language
    • good at json, parallel task, network request, etc
    • lots of packages
  • dependencies

    • other code (eg. library)
    • node does not have big standard lib
  • are deps bad?

    • depends
    • does introduce overhead
    • you can bundle to make it better
  • new syntax

    • using import (es module)
    • import nodejs internals with node: prefix
      import fs from "node:fs"
      
    • every npm name is taken, we couldn't add anything new, hence new namepsace
  • argument parsing

    • old way:
      // get everything from STDIN, split by whitespace
      // eg. [node, mycli, --ls]
      const args = process.argv
      
  • argument parsing

    import {parseArgs} from "node:util"
    const input = process.argv.slice(2)
    const options = {
    	silent: {
    		type: 'boolean',
    		short: 's'
    	}
    }
    const {values} = parseArgs({input, options}):
    
  • fetch

    • make http request
    • its available in node 18
    • built on top of undici (http/1.1 client)
    • has web streams api
    // available globally
    const response = await fetch("...")
    const body = await response.json()
    // you get JSON
    {
    	...
    }
    
  • demo to add new git subcommand the old way

    // very long example
    // ...
    
  • demo with new way

    // very short example (less than 10 lines)
    // ...
    
  • test runner

    • basic api to do this
    • eg. mocha but builtin to node
    import test from "..."
    test("synchornous test", (t) => {
    	//...
    })
    // also works async
    
  • recursive file system ops

    import {rm} from "node:fs/promises"
    
    // experimental 
    import {cp} from "node:fs/promises"
    
    // doesn't exist yet, open pr
    import {readdir} from "node:fs/promises"
    
  • whats next

    DISCLAIMER: complete speculation

    • glob?
    • self contained executable
    • typescript (lol - i wish)


Children
  1. Aminamos
  2. Hunt
  3. Kevinslin

Tags

  1. node-js
  2. cli
  3. javascript

Backlinks