4 January 2023

Issue 004: Build your own Next.js

Web Builders Digest — Issue 4

Rico Sta. Cruz @rstacruz

Do you need Next.js just to get SSR working? Maybe there’s another way. Hey! I send out emails like these regularly, so you can join me in my learning journey. Subscribe below! 👇

Build your own Next.js framework


  • vite-plugin-ssr gets you Next-like file system routing and SSR features as a DIY library.
  • It offers flexibility that other SSR frameworks don’t.

There’s a lot of frameworks for server-side rendering (SSR), and they’re all highly-opinionated. Sometimes these opinion can clash with what you want. Instead… what if we don’t use a framework?

vite-plugin-ssr is an alternative. It requires a bit more DIY’ing, but it unlocks flexibility that others don’t quite have:

It’s not a framework. It’s a library that lets you build your own framework. I think this makes for a great playground for experimenting with new tech!

Make things slower to make things feel fast


  • Functions taking a long time in the browser? Try pausing execution with await and setTimeout.
  • It will take longer to run, but it will make the UI feel faster.

I just came across a unique performance optimisation that’s just so obvious: what if we make functions pause every now and then to breathe?

Using async/await makes this very easy. A calling simple function to use setTimeout(0) will allow other things to run in the background. It’s really counter-intuitive, but pausing work periodically can things feel faster by making UI feel more responsive.

async myLongRunningFunction() {
  for (let i = 0; i < list.length; i++) {
    // Every 5 items, let other things run
    if (i % 5 === 0) await yieldToMain();

function yieldToMain() {
  return new Promise((resolve) => setTimeout(resolve, 0));

GraphQL? Rest? How about neither


  • Wildcard allows building API’s with functions, kind of like RPC.
  • It’s less verbose than GraphQL, more expressive than REST.

When building an API, it seems the only choices are GraphQL and Rest. But before there was Rest, it was popular to expose raw, arbitrary functions called remote procedure calls (RPC’s.)

RPC’s don’t require you to to build your data model as objects and resources like GraphQL and Rest do, which might make it a good fit for simpler API’s.

Build-your-own linters


  • Sylver is a way to write tools for code. Today, it supports JavaScript, Go, and JSON.
  • Use it to write your own custom lint rules.

I recall seeing places like Facebook have custom linters for their code which can validate business logic—for example, enforcing the use of design tokens for building UI’s.

Building linters can probably be done by hacking around a JavaScript parser like Esprima, but it looks like there’s an interesting alternative now. Sylver looks promising for this use case!

Compiling TypeScript to Lua


  • Write Lua scripts using TypeScript.
  • Lua is used in Neovim, Hammerspoon, and even games like WOW and Dota.

Lua has been a great language to learn, and writing Neovim and Hammerspoon plugins feels great. However, it still feels a bit rough around the edges compared to something like JavaScript: even simple things like map() don’t have native equivalents in Lua.

I just found we can now write Lua scripts as TypeScript! TypeScriptToLua is a compiler that can do exactly what its name says it can do.

Thanks for reading! I'm Rico Sta Cruz, I write about web development and more. Subscribe to my newsletter!