I'm writing a web framework

Yet another framework for the web, but different (sort of).

Spencer
Spencer
I'm writing a web framework

Photo by Daria Shevtsova from Pexels

TL;DR: a TypeScript, MVC framework that delivers server-rendered HTML.

Prelude

Every so often, an article like "Second-guessing the modern web" from Tom MacWright makes it's way around the internet.

He starts with:

The emerging norm for web development is to build a React single-page application, with server rendering

And concludes with:

But I think there are a lot of problems that are better solved some other way. There’s no category winner like React as an alternative. Ironically, backends are churning through technology even faster than frontends, which have been loyal to one programming language for decades. There are some age-old technologies like Rails, Django, and Laravel, and there are a few halfhearted attempts to do templating and “serve web pages” from Go, Node, and other new languages. (emphasis mine)

Sometimes there are short pieces like this:

frontend development is over-complicated.

Or, my own opinions (with far less reach) based on my experiences building and maintaining a Node backend with a React frontend as the sole developer.

Photo by cottonbro from Pexels

Context

I've written in a few places on this blog about what's happening in the JavaScript ecosystem broadly. The trends I continue to see is a focus on the so-called modern web, which is defined by Static-Site Generation, SPA frameworks (chiefly React), and serverless infrastructure.

On the backend, there's a movement towards microservice APIs, and Nest.js is rapidly gaining steam there.

Everything I'm seeing is moving towards greater complexity - a greater number of parts. The frameworks and libraries do a great job of masking this, but

Photo by Mohamed Almari from Pexels

Gap

I love JavaScript, and I'm learning to love TypeScript too - but MacWright is correct that there isn't any category winner in the likes of Rails, Django, or Laravel for Node or TypeScript.

As a whole, I think the JS ecosystem has been entirely focused on SPAs since Backbone was first released in 2010 (and subsequently a slurry of frameworks including Ember, Angular, React, Vue, Svelte and others). React took the crown in the end and has not been unseated. The modern web has lots of promises, but is overly complicated (read: many moving parts) for a majority of applications.

There are a great number of meaningful applications that can be built using these so-called "old-style" approaches: a monolith serving dynamic, server-rendered HTML over HTTP. Django, Rails, and Laravel are strong evidence of this point.

And, I largely believe that the JavaScript community has used the SPA as a hammer-nail solution and now every project starts with create-react-app whether or not the functionality justifies it.

But, I can't really blame them either - what options do you have if you want to work in JavaScript?

Approach

I'm proposing a TypeScript, MVC framework that delivers server-rendered HTML.

Monolithic (Against Complexity)

The problems of complexity are solved by having fewer moving parts. Monoliths can be magestic.

The entire application stack should ideally run in a single-process, especially in development. It should be easy to reason about the system as a whole.

No routing or state on the client side to manage. Everything happens in a state-less, request/response model in a server-side process that delivers HTML. Routes are declarative.

Using technology like TailwindCSS and AlpineJS, you can build beautiful interfaces with some interactivity but never need to compile CSS/SASS/LESS or bundle/transpile JS. Turbolinks can bring a lot of the UX benefits of an SPA to a server-rendered application.

TypeScript

The type-safety over plain JS provides many benefits for going fast.

Integration with IDEs makes picking up codebases you haven't touched recently much easier since you can quickly see parameters, return values, and the compiler lets you know if you've gotten it wrong.

Increasingly, TypeScript has been adopted across organizations and has gained a lot of mindshare. It shows no signs of slowing adoption over the next years.

TypeScript also has a built in JSX capabilities (see below).

JSX Templating

TypeScript comes with a built-in JSX compiler, which means that you don't need any further build process or templating language in order to compile templates that produce HTML.

As a proof of concept, I've built a package that allows you to use JSX as a templating engine with Nest applications. In part thanks to React, JSX is quite familiar.

A post for another time - but there are numerous benefits to using JSX as a templating engine over something like Nunjucks or Handlebars. Here are a few big ones:

  • Type-safe templates
  • Native support for components with typed params
  • Don't compile templates at runtime (no reading off the file-system); builds fail if templates don't exist

Community Packages; Seamless Integration

The framework should build upon the numerous, amazing, stable packages available in the broader JS ecosystem - but they should be integrated seamlessly. In an ideal world, you could build a whole application with a single top-level production dependency:

{
  "dependencies": {
    "@framework/core": "1.0.0"
  },
  "devDependencies": {
    "@framework/testing": "1.0.0"
  }
}

The framework should not need to build its own ORM but pull from great packages like TypeORM - that's a problem that has been solved before. Myriad other components should come from established packages that are seamlessly integrated.

Batteries Included

The framework should take care of all the necessities to build a production-grade application - and no more.

Things like security via CSRF protection, form validation, error handling, and logging should work out of the box.

Deciding where to draw the line is more art than science, but there's lots to be learned from Rails, Laravel, and Django.

Introducing Sipp

I'm aiming to take this approach and introduce a framework for building magestic monoliths in TypeScript. See more at sipp.dev.

Further Reading

"Second-guessing the modern web", Tom MacWright

If not SPAs, what?, Tom MacWright

"In Defense of the Modern Web", Rich Harris

"Moving my serverless project to Ruby on Rails", Alex Kotliarskyi

"Unpopular Opinion: Nodejs and Insert SPA Framework is the Wrong Choice for My Next Indie Hacker Project, yours truly

"The Majestic Monolith", DHH

"Choose Boring Technology", Dan McKinley

Update Nov 15, 2020: Moving context to its own post. Compiling a further reading secion.

Update Oct 31, 2020: Adding link to MacWright's follow up post, If not SPAs, what? and context.