4 January 2023

Issue 004: Build your own Next.js

Backdrop image
Digest Issue 004
In this issue SSR with Vite _ Optimizing frontend tasks _ An alternative to GraphQL _ Making your own linter _ More uses for TypeScript
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

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!


  • 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.

Make things slower to make things feel fast

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.

Code example ●●●
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));


  • 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.

GraphQL? Rest? How about neither

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.


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

Build-your-own linters

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!


  • 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.

Compiling TypeScript to Lua

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.


  • Write Lua scripts using TypeScript.
  • Lua is used in Neovim, Hammerspoon, and even games like WOW and Dota.
Thanks for reading! I'm Rico Sta Cruz, I write about web development and more. Subscribe to my newsletter!