A la carte Web Development

Stop using JS Frameworks is something I’ve been advocating for years now, and a
legitimate question I get is what do you replace it with?

The answer is “a la carte” web development.

Instead of picking a monolithic solution like a web framework, you just pick
the pieces you need. I don’t mean any old random pieces, below I am going to
outline specific criteria that need to be met for some components to
participate in a la carte web development.

To get a better feel for this let’s start by looking at what a web framework
“normally” provides. The “normally” is in quotes because not all frameworks
provide all of these features, but most frameworks provide a majority of them:

Framework

Model

Tooling and structure

Elements

Templating

State Management

All good things, but why do they have to be bundled together like a TV dinner?

A la carte

“A la carte” web development does away with the framework, says just
use the browser for the model, and the rest of the pieces you pick and choose
the ones that work for you. In a la carte development each bullet point is a
separate piece of software:

A la carte

Tooling and structure

Defines a directory structure for how a project is put together and provides tooling such as
JS transpiling, CSS prefixing, etc. for projects that conform that directory structure.
Expects ES6 modules with the extension that webpack, rollup, and similar tools presume, i.e.
allow importing other types of files, see webpack loaders.

Elements

A library of v1 custom elements in ES6 modules. Note that these elements must be provided in ES6
modules with the extension that webpack, rollup, and similar tools presume, i.e.
allow importing other types of files, see webpack loaders.
The elements much also be “neat”, i.e.
just HTML, CSS, and JS. No SCSS or templating libraries.

Templating

Any templating library you like, as long as it works with v1 custom elements.

State Management

Any state management library you like, if you even need one.

The assumptions needed for all of this to work together are fairly minimal:

ES6 modules and the extension that webpack, rollup, and similar tools presume, i.e.
allow importing other types of files, see webpack loaders.

The base elements are “Neat”, i.e. they are JS, CSS, and HTML only. No additional
libraries are used, such as a templating library. Note that sets of ‘neat’ elements also conform
to #1, i.e. they are provided as webpack/rollup compatible ES6 modules.

Such code will natively run in browsers that support custom elements v1. To get
it to run in a wider range of browsers you will need to add polyfills and,
depending on the target browser version, compile the JS back to an older
version of ES, and run a prefixer on the CSS. The wider the target set of
browsers and the older the versions you are targeting the more processing you
will need to do, but the original code doesn’t need to change, and all those
extra processing steps are only incurred by projects that need it.

Concrete

To move this proposal beyond just theoretical I’ve been developing and
porting applications over to this model for the past few months.

We just published pulito, a stake in the ground for what a “tooling and
structure” component looks like. You will note that it isn’t very complex, nothing more than an opinionated
webpack config file.

Similarly we’ve published our set of “neat” custom elements
skia-elements. A small set of
elements that is still very much a work in progress. Documentation and live
demos for skia-elements can be found on
jsdoc.skia.org.

We have used Redux in an experimental app that never shipped and haven’t needed
any state management libraries in the other applications we’ve ported over, so
our ‘state management’ library is still an open question.

Example

What is like to use this stack? Let’s start from an empty directory
and start building a web app:

$ yarn init
$ yarn add pulito

We are starting from scratch so use the project skeleton that pulito provides:

$ unzip node_modules/pulito/skeleton.zip
$ yarn

We can now run the dev server and see our running skeleton application:

<body><tabs-sk><buttonclass=selected>Some Tab</button><button>Another Tab</button></tabs-sk><tabs-panel-sk><div><p> This is Some Tab contents.</p></div><div>
This is the contents for Another Tab.
</div></tabs-panel-sk><example-elementactive></example-element></body>

Now restart the dev server and see the updated page:

$ make serve

Why is this better?

Web frameworks usually make all these choices for you, you don’t
get to choose, even if you don’t need the functionality. For example, state
managament might not be needed, why are you ‘paying’ for it, where ‘paying’
means learning about that aspect of the web framework, and possibly even
having to serve the code that implements state managment even if you never
use it. With a la carte development you only include what you use.

An extra benefit comes when it is time to upgrade. How much time
have you lost with massive upgrades from v1 to v2 of a web framework?
With ‘a la carte’ developement the upgrades don’t have to be monolithic.
I.e. if you’ve chosen a templating library and want to upgrade to
the next version you only need to update your templates, and not have to
touch every aspect of your application.

Finally, ‘a la carte’ web development provides no “model” but the browser. Of
all the things that frameworks provide, “model” is the most problematic.
Instead of just using the browser as it is, many frameworks have their own
model of the browser, how DOM works, how events work, etc. I have gone into depth on the issues previously, but
they can be summarized as lost effort (learning something that doesn’t
translate) and a barrier to reuse. What should replace it? Just use the
browser, it already has a model for how to combine elements together, and now with custom
elements v1 gives you the ability to create your own elements, you have all you
need.

Let a thousand flowers bloom

One of the most important aspects of ‘a la carte’ web developement is that it
decouples all the components, allowing them to evolve and adapt to user needs
on a much faster cycle than the normal web framework release cycle allows.
Just because we’ve published pulito and skia-elements doesn’t mean we believe
they are the best solutions. I’d love to have a slew of options to choose from
for tooling, base element sets, templating, and state management. I’d like to
see Rollup based tools that take the place of pulito, and a whole swarm of
“neat” custom elements sets with varying levels of customizability and breadth.