• Stars
    star
    735
  • Rank 59,377 (Top 2 %)
  • Language
  • License
    MIT License
  • Created over 7 years ago
  • Updated over 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A tiny guide to non fancy, high-value Node.js things

Tiny Guide to Non Fancy Node

A tiny guide to non fancy, high-value Node.js things. Because we're folks that want to build fun things, rather than spending time fighting our tools.

Introduction

Node.js is a truly neat piece of software. It has one of the largest programming communities, and somehow both a very low barrier to entry and a high skill cap. Picking Node as the hammer in your programming toolbox is not a bad choice.

Node can be a little overwhelming though. Because of the low barrier to entry for both writing and publishing software, it can sometimes become hard to find exactly what you need. That's why this tiny guide exists: a little set of opinions to help guide you in the vast world of Node.

Obviously other people will have different opinions, and that's cool. This is what I've found to work for me, over the years. It's fine if we disagree. But there might be a chance you'll find this works for you too.

Disclaimer: If you disagree enough to get angry at this guide, I urge you to take a breath, step back and reconsider. Feel free to write your own guide; hell - having more perspectives and resources is a great thing! Remember that kindness matters

Programming style

There's style, and there's syntax. Generally discussions about punctuation and other linting things are boring, so use standard and worry about solving actual problems instead. standard --fix will even take care of formatting code for you; it's been around for a while and generally gets the job done.

language version

ES3 is generally all you need. Really? Yup, really. The Array methods in ES5 are nice, and template strings are useful - but that's it. var is performant, and flexible. callbacks are the unifying interface for asynchronous programming, and for-loops are about as fast as you'll get. Using a tiny subset of the language makes your code stable, readable and predictable. Exactly the way we like it.

require

Don't bother with import, it's unstable. require() has worked since the dawn of Node, and works reliably for any scenario you can come up with. And no need to worry about "tree shaking" / "dead code elimination" - unless you've got extremely complicated applications it won't matter. At that point you'll probably have much larger problems to worry about.

functions

We don't need 13 different types of functions. Using function foo () {} will cover all your bases. Yup, even arrow functions aren't worth it - we aim for boring; and removing arguments and this from arrow functions makes arrow functions weird and hard to debug.

Async

Callbacks are your ticket. They're fast, easy to reason about and easy to debug. If you ever find yourself struggling with them, consider naming and splitting them. Other paradigms build on top of callbacks and will probably make things more complicated. For example by ignoring error handling in examples, swallowing errors all together or far worse. You want errors to be predictable.

Speaking of errors: use throw to crash and burn your program (e.g. programmer errors, for example a wrong type) and use callbacks for expected errors (e.g. oops, wrong input - try again).

The feross/run-* family of packages is truly wonderful. They'll give you virtually all you need for working with callbacks efficiently. There's also map-limit which is my go-to hammer when needing to run an array of things, in series, parallel or something in between.

If you ever need composable async in Node, consider using streams. The streams2 API isn't pretty, but it's worth learning. Streams can be passed around synchronously and will send data from one place to another. They're ideal for creating composable, reusable APIs. Check out mississippi on GitHub to learn more about good streams packages.

Testing

The Test Anything Protocol (TAP) has existed for years, and works in almost every language. tape is the way to use it in Node. Don't worry about fancy (Promise based) parallel test runners; if they provide any measurable performance improvement then your code is probably too complicated in the first place. Instead consider removing all IO from your tests for example.

If you want pretty printing for TAP, use tap. If you want code coverage reporting, use nyc.

Use dependency-check to make sure you didn't miss any deps. greenkeeper is neat if you maintain applications.

Functional utility toolbelts

Grab bag packages often lead to code creep; don't use 'em. If there's 60 functions exposed in any given package, chances are that given enough time the code base will asymptotically start using a higher percentage of these functions. And that's not good; there's a thing as being too dependent on external code.

Databases

level is the only database. Use membdb when testing and developing. Use subleveldown to split your database. Check out the wiki for more modules; there's one for virtually anything you could need (replication, caching, LRU, etc.)

I'm not a fan of other databases as they're usually peer dependencies. If you're building something, you probably want to optimize for iteration - not so much other things. And level excels at that. Unless you're building a bank; I wouldn't trust myself to build a boring money transaction system in Node. Take advice from other people if you're planning to do stuff like that.

Devops

Use lil-pids for process management and taco-nginx to expose processes to the outside world. scp(1) or npm are generally enough to deploy your stuff with. Use npm install / npm start for your apps to be predictable. You probably don't need Docker - remember that Node is a cross platform virtual machine already; if you get started Node is probably all you need. You can always get fancy later.

Distributed systems

You probably don't need high performance distributed systems stuff when writing applications. Ask yourself: do you really need to run this on more than one machine? This is some of the stuff we're working on during my day job though; often it just turns a problem into a distributed problem.

If you do need to run something on multiple machines though (e.g. live video streaming!) consider using hypercore (distributed streams) or hyperdrive (distributed filesystem). They're neat, secure modules that make writing distributed system stuff relatively painless.

APIs

I've recently been working on merry which uses streams, fast logging and has loads of conventions. It's all of my opinions around API design turned to code.

Static typing

It's generally a good idea to validate assumptions you make. This helps catch mistakes early and makes fixing them easier later on. I like using Node's built-in assert() package for this. Got an input type you want to validate? Assert it. Expect certain config values to exist? Assert it. Because I use it in all my packages, having an extra compile check for static types doesn't make sense for me. When deploying production code unassertify removes the extra checks.

When building APIs json-schema is a great way to validate assumptions made about incoming JSON. When building custom wire protocols protocol-buffers and similar are great.

Frontend

I've recently been working on choo which uses pure HTML, JS and has a clean architecture. It's all of my opinions around frontend applications turned to code.

To serve frontend code I use bankai. It's based on browserify which is a super stable tool to build frontend stuff. Boring and stable is the name of the game. budo is similar to bankai, maybe you'll like it too.

For css there's sheetify and tachyons. sheetify allows you to require css from node_modules. It's built right into bankai so it's easy to work with. tachyons is a sane CSS system. It might feel awkward at first, but once you get past the bump you'll be building maintainable websites faster than ever before.

Accounts, authentication and the like

We're currently working on easy to setup account stuff through township but it's still a work in progress. If there was anything that scratched our itches already we'd be using it.

Native development

electron is cool. I've never built a mobile app, so I can't comment on that - probably building a website would be where I'd start though.

Wrapping up

Yup, and that's it. These are my boring tools for writing software. Obviously there's much more tools to be discovered, but npm should be your friend. I hope this little guide can at least help you out a little when getting started in the wonderous world of Node.

PS. The fancy name for the tech described in this guide is The Lebron Stack. We don't kid. Happy coding!

License

MIT

More Repositories

1

rust-for-js-peeps

Know JS, want to try Rust, but not sure where to start? This is for you!
1,262
star
2

vmd

๐Ÿ™ preview markdown files
JavaScript
1,175
star
3

notes

notes on things
839
star
4

futures-concurrency

Structured concurrency operations for async Rust
Rust
345
star
5

github-standard-labels

Create a standard set of issue labels for a GitHub project
JavaScript
241
star
6

sheet-router

fast, modular client-side router
JavaScript
223
star
7

pretty-hot-ranking-algorithm

Algorithm that measures how relevant a given data set is, kinda like Reddit
JavaScript
204
star
8

markdown-to-medium

Publish markdown to medium
JavaScript
198
star
9

html

Type-safe HTML support for Rust
HTML
186
star
10

barracks

๐Ÿšž action dispatcher for unidirectional data flows
JavaScript
177
star
11

virtual-html

๐ŸŒด HTML โ†’ virtual-dom
JavaScript
174
star
12

dotfiles

Linux desktop config
Shell
127
star
13

es2020

Because in hindsight we don't need most of ES6
JavaScript
126
star
14

miow

A zero-overhead Windows I/O library, focusing on IOCP
Rust
109
star
15

fsm-event

๐ŸŽฐ stateful finite state machine
JavaScript
91
star
16

changelog

Changelog generator
Rust
85
star
17

vel

minimal virtual-dom library
JavaScript
84
star
18

fd-lock

Advisory cross-platform file locks using file descriptors
Rust
69
star
19

exponential-backoff

Exponential backoff generator with jitter.
Rust
66
star
20

memdb

Thread-safe in-memory key-value store.
Rust
64
star
21

previewify

Preview tool for applications
JavaScript
62
star
22

server-router

Server router
JavaScript
61
star
23

speaking

Slides, proposals and more for talks I give
JavaScript
57
star
24

electron-collection

Set of helper modules to build Electron applications
JavaScript
57
star
25

cache-element

Cache an HTML element that's used in DOM diffing algorithms
JavaScript
56
star
26

mdjson

๐Ÿ“– Transform markdown to an object where headings are keys
JavaScript
55
star
27

context-attribute

Set the error context using doc comments
Rust
53
star
28

newspeak

๐Ÿ’ฌ natural language localization
JavaScript
51
star
29

copy-template-dir

High throughput template dir writes
JavaScript
51
star
30

assert-snapshot

Snapshot UI testing for tape tests
JavaScript
50
star
31

polite-element

Politely waits to render an element until the browser has spare time
JavaScript
45
star
32

choo-persist

Synchronize choo state with indexedDB
JavaScript
44
star
33

power-warn

Warn on low power level.
Rust
42
star
34

base-elements

A selection of configurable native DOM UI elements
JavaScript
41
star
35

nanostack

Small middleware stack library
JavaScript
40
star
36

millennial-js

๐Ÿ’
CSS
39
star
37

on-intersect

Call back when an element intersects with another
JavaScript
35
star
38

github-templates

Generate .github templates
Rust
35
star
39

microcomponent

Smol event based component library
JavaScript
35
star
40

observe-resize

Trigger a callback when an element is resized
JavaScript
33
star
41

hypertorrent

Stream a torrent into a hyperdrive
JavaScript
31
star
42

npm-install-package

Install an npm package
JavaScript
30
star
43

async-iterator

An async version of iterator
Rust
30
star
44

rust-lib-template

Rust lib template repository
Rust
29
star
45

heckcheck

A heckin small test generator
Rust
29
star
46

maxstache

Minimalist mustache template replacement
JavaScript
28
star
47

normcore

No-config distributed streams using hypercore
JavaScript
28
star
48

chic

Pretty parser error reporting.
Rust
27
star
49

winstall

Install all dependencies required by a project
JavaScript
27
star
50

validate-formdata

Data structure for validating form data
JavaScript
25
star
51

playground-tide-mongodb

Example using tide + mongodb
Rust
24
star
52

playground-nanoframework

Building tiny frameworks yo
JavaScript
24
star
53

hyperlapse

Distributed process manager
JavaScript
23
star
54

promise-each

Call a function for each value in an array and return a Promise
JavaScript
23
star
55

omnom

Streaming parser extensions for BufRead
Rust
23
star
56

virtual-widget

Create a virtual-dom widget
JavaScript
22
star
57

tasky

fluent async task spawning experiments
Rust
22
star
58

debug-to-json

๐Ÿ”ง Convert debug logs to JSON
JavaScript
22
star
59

http-sse

Create server-sent-events
JavaScript
21
star
60

kv-log-macro

Log macro for logs kv-unstable backend
Rust
21
star
61

initialize

Generate a fresh package
JavaScript
21
star
62

github-changelist

Generate a list of merged PRs since the last release
Rust
21
star
63

assert-html

Assert two HTML strings are equal
JavaScript
21
star
64

workshop-distributed-patterns

Learn how to create robust multi-server applications in Node
HTML
20
star
65

crossgen

Cross compilation template generator
Rust
20
star
66

electron-crash-report-service

Aggregate crash reports for Electron apps
JavaScript
19
star
67

pid-lite

A small PID controller library
Rust
19
star
68

playground-virtual-app

playground with some virtual-* tech
JavaScript
19
star
69

virtual-raf

Create a RAF loop for virtual-dom
JavaScript
19
star
70

promise-map

Map over an array and return a Promise.
JavaScript
19
star
71

how

how(1) - learn how to do anything
Rust
18
star
72

secure-password

Safe password hashing.
Rust
18
star
73

futures-time

async time combinators
Rust
18
star
74

microanalytics

Capture analytics events in the browser
JavaScript
18
star
75

noop2

No operation as a moduleโ„ข
Makefile
18
star
76

github-to-hypercore

Stream a github event feed into a hypercore
JavaScript
17
star
77

hyperreduce

Distributed reduce on top of hypercore
JavaScript
17
star
78

microframe

Smol requestAnimationFrame package
JavaScript
17
star
79

github_auth

Authenticate with GitHub from the command line.
Rust
17
star
80

rust-cli

rust(1) cli prototype
Rust
16
star
81

virtual-streamgraph

Create a virtual-dom streamgraph
JavaScript
16
star
82

extract-html-class

Extract all classes from html
JavaScript
16
star
83

templates

Template files used to generate things
Shell
16
star
84

from2-string

Create a stream from a string. Sugary wrapper around from2
JavaScript
16
star
85

fin

Simple finance visualizations
JavaScript
16
star
86

async-collection

Collection of async functions
JavaScript
15
star
87

buffer-graph

Resolve a dependency graph for buffer creation
JavaScript
15
star
88

document-ready

Document ready listener for browsers
Rust
15
star
89

choo-pull

Wrap handlers to use pull-stream in a choo plugin
JavaScript
15
star
90

json-stream-to-object

Parse a JSON stream into an object
JavaScript
15
star
91

formdata-to-object

Convert a formData object or form DOM node to a KV object
JavaScript
14
star
92

promise-reduce

Reduce an array and return a Promise
JavaScript
14
star
93

ergonomic-viewport

Get the current ergonomic viewport
JavaScript
14
star
94

choo-model

Experimental state management lib for choo
JavaScript
14
star
95

shared-component

Share a component instance inside a window context
JavaScript
13
star
96

multipart-read-stream

Read a multipart stream over HTTP
JavaScript
13
star
97

nanopubsub

Tiny message bus
JavaScript
13
star
98

server-render

HTML server rendering middleware
JavaScript
13
star
99

const-combinations

Experiment to get k-combinations working as a const fn
Rust
13
star
100

noframeworkframework

[wip]
JavaScript
12
star