A JavaScript-Free Frontend

Matt Reyer on March 11, 2019

Slimvoice - A Webapp Without JavaScript is a series where I document how I rebuilt my app, Slimvoice, using as little JavaScript as poss... [Read Full]
markdown guide

I really like the principles! <details>/<summary> in particular, I'm a big fan of them for collapsible sections.

I want to point out that for some interaction to be fully accessible to users, you might need JS. This is for the modal in particular. Modals have specific prescribed user interactions, outlined in the WAI-ARIA Authoring Practices. You need to enhance the focus management so that you focus the dialog (or the first interactable element, depending on what recommendation you follow). Using a checkbox and label to do that seems like an abuse of semantics.

One implementation of progressively enhanced dialog that I like is Github's details-dialog. It handles a number of interactions better than the plain version. And in case JS fails, the UI is operable by some users still (goals that I believe match yours :) ).

HTML is great at providing accessibility by default, but it does not mean that everything is best served without any JS. I think this is a big reason why the dialog element has not gained much traction outside of Chrome; there is behaviour that still is not clear without JS.

(* Speaking of HTML and labels, your forms are missing them. Many people consider that to be "cleaner", but it is simply inaccessible to many users. Not just Assistive Technlogy (AT) users, but also people who rely on translation services, cognitive disorders, and so on. I find that people will copy the examples that blog posts set out, so I would urge you to consider adding labels.)


Excellent points! Thank you for this awesome feedback.

Absolutely, the checkbox/label is definitely an abuse of semantics. Totally a hack that should not survive in the long term. However, look at the amount of code in the example from the example you sent. If you need a complex system with absolute control, then there is no problem with that. I do love the elegance and accessibility improvements of the <details> alternative you linked and will probably be migrating to that in the future. However, is it not a failing of the standard to not allow something without JavaScript whatsoever? Why was something like this never added to the standard?

<button for="my-dialog">Click Me</button>
<dialog id="my-dialog">Modal Here</dialog>

The open attribute, requiring JS, is totally missing the mark on behalf of W3C.

Unfortunately, like many other projects, accessibility typically lands at the bottom of the priority list. I am ashamed at how often this is the case and at how weak my accessibility knowledge is. Regarding the forms, I typically prefer using the placeholder as an input label. I realize this is not in the spirit of an accessible form, so how would you suggest improving it while keeping the same visual style? Use a <label> with position: absolute placed over top of the field? Is there a CSS trick for reliably hiding it when the field is filled so that it behaves just like placeholder?

By the way, if I have a <label> in a form but it is display: none, does it lose it's value to someone who needs accessibility features, or does the accessibility tech still benefit from the added semantics?


That code is 300 lines, well commented, straight from the authoring practices. That's not a big number at all, especially when the dilemma is between "inaccessible because we don't want scripts" and "accessible after scripts get here, and still operable without them".

Even with <details>, you still need to make sure that the full "modal" semantics are there, after scripts come in. This is what Github's implementation, in 200 lines :)

I understand that not having a lot of scripts is the point of the post, but I think the metric should not be the target. If the target is to provide a better experience for everyone, and you need the scripts to make it fully accessible, then I don't see a reason to skip them.

Especially when promoting it to people as something that offers a better user experience, something that they might copy verbatim, it is important to stress all use cases.

This has given me a lot of thoughts to write about progressive enhancement. I like the spirit of the post, I really do!

On the dialog spec

A big reason why the dialog element needs JS still, and has not gained much traction outside of Chrome, is that it's missing some important primitives. For example, we need primitives to render content "inert" and an element as "blocking" others. (See, for instance the inert attribute proposal)

I think the Authoring Practices go over the prescribed behaviour much better than I could.

Progress is being made, and in a way that I think will give us better tools to handle these interactions. And in any case, until then, why not enhance the markup with scripts? It is still operable without them, and serves users better with them.

Scott O'Hara has given a good overview of modal dialog accessibility, which might shed more light.

On form labels

By the way, if I have a in a form but it is display: none, does it lose it's value

Correct, it does not expose them. Also correct that placeholder does not get exposed.

This is for a good reason; imagine all the content on the web that is rendered with "adaptive design" practices. Large subtrees of applications get hidden conditionally with media queries, so the Assistive Technology (AT) user should not have to go through them.

There is a way to visually hide content without hiding it from AT. It is often used as a bandaid though, and it can confuse sighted AT users!

Form labels are not just for AT users. There is good research out there that they help fill rates and comprehension.

As you say, a placeholder disappears as soon as you start typing; the user can get lost, have to Ctrl+X Ctrl+V just to remember what they were typing etc. That can range from annoying to stressful.

(I know I said it a couple of times, but when promoting a practice that is better for the users in a post, having inaccessible examples goes counter to the point, and can propagate them. Accessibility is most often not about special skills, but about not removing the default semantics, like the labels).

I outlined my own gripes and suggestions about forms in a talk. Some sites omit labels, which renders forms untranslatable. As an immigrant, that can lock me out of sites, when the original intent was for the form to be clean and welcoming!

Another source I like is Adam Silver's Form Design patterns.

Material Design has a pattern of "floating" the label up when you start typing. At the end, you still need visual space to accommodate the label. That text also tends to be small (and worse sometimes, low-contrast), which ime renders a lot of the benefits of labels moot.

The fact that "no labels is more clean" is an assumption to be challenged, in the same spirit as the post. I want to see more of that :)


"...if I have a in a form but it is display: none, does it lose it's value to someone who needs accessibility features..."

If you set display: none, it will be hidden from screen readers, same as visual users. Same goes for visibility: hidden.

This is why your label + checkbox hack unfortunately needs to die--it will likely be completely inoperable to a keyboard user, and totally incoherent to a screen reader user.

Don't get me wrong, I love the spirit and goal of this post, but you REALLY should just be biting the bullet and using a <button> + javascript for toggling. Honestly, the amount of extra JS you need to do it is so tiny that there's really no excuse for it.

but you REALLY should just be biting the bullet and using a <button> + javascript for toggling. Honestly, the amount of extra JS you need to do it is so tiny that there's really no excuse for it.

Agreed. I really appreciate the intent of this post, and that modal hack is clever, but for the reasons already pointed out, I don't think it's worth it. And the JS is extremely simple, e.g.:

elButton.addEventListener('click', () => {

That said, I'm totally behind the spirit of his post -- just don't think extremes are necessary.

Still trying to figure out where to draw the line with my specific approaches (I strongly support accessibility). If we were all building native apps we wouldn't even have to suffer through this miserable dilemma. What needs to be asked is:

  1. Why are we trying to build apps on HTML, a medium that was originally designed for hyper*text*? Would a completely new medium be better suited for the task? (Hint: yes)
  2. If we're collectively agreeing that the language of the web is now to be used for executable programs and interfaces, then why is the HTML spec so far behind in supporting common UI tasks like this?

I made your label+checkbox hack more accessible. Works fine with a screen reader / keyboard (tried on MacOS Safari with Voiceover).

<label for="toggleControl" style="cursor: pointer;">
  <button id="toggleButton">Click Me</button>
#toggleButton { pointer-events: none; }

But still it seems a bit of overkill as already pointed out when you can do it in a few lines of js.

As for hidden text for screen readers you can use a sr-only class.

Hey Matt, I love your question #1 there. Anyone want to take a stab at it.

I used to have to work as a ZenDesk admin for years. The beast is slow. (It's a good product, not trashing it).

But should it be a full "built-in-the-browser" app? 95% of that puppy could be built on a screaming fast native app, with probably far less headache than JS library/framework/div/class hell.

Are Swift and C# junk? Some WebDevs seem to think so.

Imagine a ZenDesk app you install (uh, not built on Electron which is just more interpreted language hell) and that is not only native (i.e. beautiful to your OS), but also blazing fast.

The ONLY thing that needs to be communicated over the internet is small XML updates to CRUD tickets and user/company settings. I could scroll through tickets like I was driving Mario Cart (at today's broadband speeds).

Instead, it's like watching Space Invaders at the beginning of each round... thump, thump, thump.... and sadly never speeding up as it does near the end of each round in Space Invaders. It's like Tetris on Level 1 - permanently.

The ONLY kickback to such an idea (by companies that build such web apps) is as follows:

  1. Installs take the support of IT. (This is exceedingly rare in decent offices, but it is true that maybe some users can't install it without IT support. But shouldn't that be a good thing? When did "the average employee can be on a web browser all day" become a good thing?

  2. The software company can't easily do iterative improvement. Again, I feel this is a GOOD thing. Half the crap that software companies iterate as improvements (and rollout to their "users" without consultation) isn't helpful, but a drag on productivity to its users as they have to now figure out where the widget is that they were using on Tuesday afternoon, but it got moved on Wednesday morning. Make companies "roll out" software again. At least Salesforce sticks to a 3x/year rollout, even thought it's cloud-based, so people don't go nuts. And they can sometimes choose what to implement or not. We should all be so lucky. But what do you expect for $12.99/user/month with some of these SaaS "apps".

If I were building a company from scratch, I'm not sure I'd use hardly any Saas services at all. Heck, sad to say, but as Customer Success Manager, I saw subscription prices at multiple companies that were unbelievable. When I researched who was using what for what, it was a joke. Half the SaaS stuff got canned, and another 20% or so was somebody just wanting to look important and they were told to use a spreadsheet instead. (One was literally an all-powerful HR manager who everyone feared for all the reasons you can imagine that had subscribed the company to an ATS (Application Tracking System) for around $1500/year - for a company that did, quite literally, 2-3 hires a year. And of course, that HR Mgr spent time uploading the company logo into the system, setting up auto-reply emails, and a bunch of junk to rob the company of even further assets instead of just doing their job and dealing with benefits and managing a few hires a year. I'd love to say it was an isolated incident (and well outside the scope of this thread, I realize), but it was commonplace at a number of companies. Only because I'm a hardnose did I get some forward progress on that one, but more often, other managers are fearful of unsubscribing to SaaS businesses ("well, we might need it more soon because we are growing", or "everyone seems to like it", or "if we use a spreadsheet, it could get deleted and all the data lost" (I wish I could say this was made up, but I've heard it time and time again - and not in 2002, or 1989, but in the past 3 years.


I would actually expect the Escape key to close the modal dialog, but I suspect none of the mentioned solutions support that.
Or am I wrong?


On the topic of accessibility and

The ability to do the modal/checkbox trick above without it feeling like a hack and writing weird CSS.

I think that <details>/<summary> is a better element to enhance for these cases. I pointed out Github's implementation above, for its enhanced JS interaction, but I should also mention that its no-JS behaviour is better, because it is more navigable by keyboard. I tried the menu and settings on the site, and I was not able to reach them by keyboard. With details/summary, those would be in the tab order and announced with better roles.


There might be an alternate view that maybe logins and some modals shouldn't be. I personally am so tired of modals. What's the point of a popup blocker in our browsers anymore?


As Matt points out, when it's so blazing fast to load a new page, why not have /login on most web apps just go to a page called login.html?

And yes, I think it will be okay to leave the .html file extension on there and save an unnecessary Apache rewrite.

I've never yet seen a modal that is as functional as a standalone web page. And yes, that includes (gasp) iframes. Maybe just skip the whole hassle? The app still works without modals, right?


And yes, I think it will be okay to leave the .html file extension on there and save an unnecessary Apache rewrite.

Why not just login/index.html? No rewrite and still a nicer URL, all you need is something like

DirectoryIndex index.html

From the documentation:

When a directory is requested, Apache may be configured to send a particular file within that directory automatically.


A mistyped HTML tag is generally obvious, the page will not look as intended. A validator browser extension will double check and help you be more thorough in development.

That's right, calling a non-existent function in JavaScript will throw an error that will be easy to debug. But how does one debug an exception thrown by some library that is a sub-dependency three levels deep downloaded from npm, that you didn't write, is obscure to begin with, and is now minified in your production build? Whether the bug gets solved or not, chances are good that many hours will be spent trying to figure it out. I've been there more times than I care to recall.

Have you ever deployed Bugsnag with your frontend code? Some problems are easily solved, but after a certain point the exceptions become unwieldy, submitted in foreign languages, and exhibit a myriad of other unreproducable issues.


That is impossible in the current JavaScript ecosystem.


It's totally possible. Write your helpers, don't use 3rd party libraries!
You can have templates, module, components even event driven functionality in a few lines of code. Compatible with all browsers and zero dependencies, working in all server technologies, even opening plain html file.
I wrote about that here

Problem: There are too many js libraries, and people use them excessively.

Solution: "Just write your own framework then!"

... wow. You should do this. Please. I mean it. Write and use your own framework and then build a web app with it. A web app that does something, not a todomvc.com app. Report back when you understand why this is a learning exercise and most people use libraries managed by thousands of active users instead of one random dude.

"Do not use libraries with many sub dependencies"

Ooook. Do you actually use NPM? Have you ever? Did you miss the left-pad fiasco? Yes, simple. 2/3rds of the internet went down because managing JS dependency chains is "simple". Words of someone who has never built a JS based front-end.


I already did it. I have production web apps that uses my own tools with almost zero dependencies, just some 3rd party helper components (front end). Are time perdurable, easy for me to debug and very easy to add new features, not having to learn anything new every time I need to apply new feature to my project.

Maybe my short answer in certain context was misunderstood and not explains the intention of my blog post linked.
In my opinion, there's a trend to use the complex frameworks, with more than 1000 dependencies, compilation steps, ... for doing every kind of web apps, including the simple ones. In my experience, the more dependencies and more steps (compilations, …), the more possible problematic situations.

My post isn’t really about creating a React or Angular competitor, is just about a simple exercise to realize that there are some features on these frameworks that can be solved relatively easy creating a simple helper. Maybe you don't need an entire frameworks to just take advantage of 2, 3, or 4 features it supplies. As I said in the post, We don't want to reinvent the wheel. Ok, that's a good point, but a lot of frameworks don't have just wheels, they build entire trucks.

I don’t pretend to write a framework, I only invite to think if with on ore two helpers developed by your own, maybe can solve your problem without the necessity to deal with these complex ecosystems.

Finally, I don’t say no one has not to use frameworks. There’s a lot of situations where frameworks are the best solution definitely. I just say, be sure you really need to use and learn a new tool before going for it.

2/3rds of the internet did not go down. Nothing serious happened at all.

Leftpad was a rather useless package that was included in some other major packages and caused many automated builds to break. No working code was affected and no competent team was using that package directly in their apps in the first place. The underlying was actually about NPM being a poorly designed system that allowed packages to be completely removed in the first place.

If anything, the incident was a good call for better dependency management in the JS community to avoid dependency sprawl and highlighted how important it is to bring a real standard library to the language.

Nothing serious happened at all.

the incident was a good call for better dependency management

Wait I thought nothing serious happened at all?

The entire event was serious and highlighted some major flaws in the way we handle dependencies. You're right, I agree.

I never claimed to have experience in writing JS libraries or frameworks

Please, contribute, but perhaps refrain from comments like "simple: don't do that thing!" Maybe you can see how this could be annoying to some of us.


Write and use your own framework and then build a web app with it. A web app that does something

Of course you realize that every framework out there originated as someone's pet project, someone unsatisfied with existing frameworks, and with a different set of problems to solve.

So yeah, I would absolutely encourage anyone to build what they need. And maybe that's not a huge one-size-fits-all "framework", but a simple set of modules, tailor made for their specific needs.


True enough, but on the other hand I very rarely find myself with broken HTML. IDEs make it very clear when you're missing a closing tag, or when things are in a different order than you intended (especially with a reformat-on-save feature enabled). In addition, JavaScript stack traces aren't always that helpful, especially when you're using a SPA framework that calls your code, or you use a lot of promises, etc.

In the last year, I can remember maybe 2 instances of broken HTML that took me some time to find, but I run into JS errors weekly, if not daily, where the exception and stack trace are useless and I spend a good 20+ minutes tracing through the code or stepping through in a debugger before I can find the bug.

In general, HTML is significantly less complex by its nature, so there's just less that can go wrong. And HTML validators are pretty solid at this point, and have been for a long time.


Sure, all of the above. Both of those are (again, in my experience) 100x easier to track down and solve than, e.g., an obscure bug caused by mistyping a property name in some callback halfway down an RxJS pipe.

And in fact, both of those can also be caught by IDEs and/or HTML validators, since attributes and elements are standardized, and anyway, the cases where "an element was used incorrectly" will cause significant problems are usually cases that are visually obvious, and thus easy enough to trace, or that cause accessibility problems, which should also be clear enough if you're doing a11y testing in the first place.

Again, it boils down to HTML having much less in-built complexity to it. I think that's the big takeaway from this article: most of the stuff we use JavaScript frameworks to accomplish are not complex enough problems to justify such a complex solution. As the author points out, there are cases where this is not true, and in those cases, sure, sprinkle in some JS. But you can get pretty far without it.


Sure it is. For one, attributes typically have effects that are obvious when missing. For another, HTML5 doesn't allow custom attributes that aren't prefixed with data-, and most HTML validators will catch them.

And anyway, you wanna talk JS, how about mistyped event names? Just last week my teammate lost hours in a weird bug that boiled down to a '$destroy' event mistyped as '$destory'.


I mean, then it would be your own fault for not checking the attribute to begin with. What's the difference?


The same can be said of events. I guess my point boils down to: anything that can go wrong in HTML has a direct analog in JavaScript, and there's a thousand extra things that can go wrong in JS as well.

Congratulations Ken for your patience in this conversation. I am impressed


A mistyped HTML tag is not gonna do much to help you fix stuff, but a call to a non-existent function in JS is gonna throw an exception with that tells you what you tried to do along with a stacktrace. Thus I think that having an exception is clearly better.

That is a strength of html, not a weakness. It's called the "robustness principle" (aka Postel's law). It's the reason the web was able to thrive, and is still thriving 30 years after its invention.

Malformed html, unrecognized tags or attributes, will not throw an exception. The browser will do its best, and in all likelihood, your users will still be able to do their jobs.


Html is entirely declarative, and there are plenty of validators out there, often built right into the IDE.

While I agree it might be nice for browsers to put something in the console when they encounter unrecognized tags or attributes (and I think some of them might already do this), I still think a silent best-efforts approach by the browser is a way better experience for users than a blank page with a hidden stack trace.


That's the crux of this whole argument, though: an unrecognized tag is not an error. Because Html tags are not instructions to be followed like an imperative program. They are semantic expressions of document structure, intended for a variety of potential clients of differing capabilities. Different browsers (and other devices) are free to interpret parts of those declarations they understand, and ignore others. Html documents can be full of tags and attributes, meant for specific clients, in different contexts.

By design, browsers are supposed to ignore anything they don't recognize. If they wrote errors to the console for every bit of unknown content, the console would be very noisy indeed.

This seems to be a hard concept for many to grasp.


Yes, and Firefox also writes warnings to the console for malformed content (known elements appearing in the wrong place, such as putting a tr element directly inside a div), mismatched open/close tags, etc.

So that should satisfy most of your concerns around mistyped html tags. The difference is that the browser won't just stop rendering the page, and in most cases the user can keep working even if something looks a little off.

But unrecognized tag and attribute names should not result in warnings in the browser. The browser has no idea whether these names might have meaning to other clients, and so it (rightfully) ignores them.

You can still catch all of these at dev/build time with an html validator. So there's much less need for console warnings if any kind.

That is decidedly not the case with JavaScript. Your JavaScript may be 100% correct from three compilers perspective, but you don't have complete control over the environment in which it runs (or if it runs at all). Putting too much responsibility on JavaScript inevitably limits the number of browsers your app can reasonably support.

Even those who "only support modern browsers", (or worse: "only support chrome", a super dickish and short-sighted attitude) cannot be assured that their script will always work. Browser plugins, malware filters, etc. can all interfere. So JavaScript needs console errors in order to help diagnose errors in the client. It's essential information.

But you don't really need that as much (or at all) with html.

  1. Please remember accessibility when implementing hacky things. For instance that checkbox thing is great and somewhat lean but it might cause trouble with certain assistive technologies. Check the :target selector for more ideas regarding the use case. ;)

  2. You can have a PWA without an SPA, just requires some JS boilerplate to initialize it. Handy for "home screen installable" non-SPA applications, that might require PWA features occasionally.

Nice article, I have been trying to keep my JS to a minimum as well to let users have a more reliable experience with less development overhead.

HTML and CSS are super powerful, and can be supercharged with JS where needed.


Javascript can be blamed of a lot of unfortunate consequences, but we should not forget what it offers. If you were building a picture gallery, you would love to perform lazy loading. With a server-side rendered only web page, you would not be able to offer such a fast experience. Actually, a service workers of about 100 line of code can outperform any server caching by offering graceful cache control (stale while revalidating, cache first for images,...), and the benefit for the user bandwith is largely worth the cost of JS.

However, I completely agree with you, there is a Javascript fatigue right now. Frameworks ship too much dependencies, web page weight more and more with unused bytes of piece of code. This is also why some big companies put a Javascript budget (a certain amount of Kb to not overpass for example). Some alternative like Preact or Hyperapp fit very well those project constraints while providing a correct development experience.


Yeah totally! I'm disappointed that so many features we expect from a modern web experience, like lazy loading, require JavaScript. I was hoping this would spur some discussion about some rethinking of HTML that might alleviate that.

For example, wouldn't it be amazing if such a thing as <img src="..." lazy="500px"> were possible such that the browser would load the image if its bounds were visible in the viewport or within 500px of the scroll position?


I cannot find where it is written, I might have saw it in one of their video: the Chrome team is working (I think it was a talk with Addy Osmani in which I heard this, correct me if I am wrong) is actually working/thinking of a lazy="true" attribute on img video and audio to help make this a de facto feature on the web. So maybe they heard your request 😉

It's changed a little since then but yes there is a built in lazyload in the pipeline 😀



No one will agree with me, but I think "lazy loading" translates roughly into "lazy devs who don't care that a web page is a document that should stand alone". I abhor that everyone feels that lazy loading is "required" for "performance".

Seriously, 70% of the time, the images are too many, are too big, are the wrong type (PNGs vs JPGs - still), or even GIFs, and the whole "page" doesn't represent a page at all, but some kind of mutating animation.

Cache! Minimize! Lazy Load!.... Uh, really? What about knocking that page down to 300Kb instead of 3000Kb and then you wouldn't have to do any of that. Plus, does no one care about all the CPU cycles you are stealing both from me (the browser of your "app"). Cache, minimize, and lazy-load all you want... my machine still has to do your work for you.


I don't think adding even more functionality to HTML is obviously. It makes it harder to implement browser engines. The added complexity makes it harder to implement browsers reliably too.

Also have a look at Alan Kay's augments on the topic:


I like the point of view in the thread you shared, but I am afraid this is the reason Linux is not spreading as much as Windows for example: features. Most of the time, you will encounter développer for the sake of a project, not pure développer for the sake of the technology. Which means, people want to scale, fast, with ready-to-use state-of-the-art technologies like lazy loading. If we were following the principle stated on the article you shared, awesome advancements security features like finger print authentication, isolated websites, etc... Would have not been implemented. Nor Services Workers, or media lazy loading, that seems obvious when you think of it. I do not agree with this article, but I appreciate the point of view, it definitively have advantage to think like this, but I think this does not fit the web and web browser. We need people that can be up and running fast, not relying on npm package that got deprecated because of loss of money and energy, and having to deal with this.


The website looks nice and renders super fast but I am met with a shit ton of errors in the console. Its responsive though which is why I went to the console in the first place!

Refused to load the font '<URL>' because it violates the following Content Security Policy directive: "default-src 'self' <URL>". Note that 'font-src' was not explicitly set, so 'default-src' is used as a fallback.

Dang! What browser are you using? I'm serving all of the fonts from my own domain, so CSP shouldn't be a problem. I don't understand where the URL <URL> is coming from. Could it be a browser extension of yours?


So I looked into it a bit more, the error is more defined as

Refused to load the font 'data:font/woff;base64,d09GRgABAAAAAGVUABEAAAAAxuQAAQABAAAAAAAAAAAAAAAAAAAAAAAAAABHREVGAAABgAAAAC4AAAA0ArgC7UdQT1MAAAGwAAAQ6AAALgxKsqRTR1NVQgAAEpgAAAH3AAAELqI5y+RPUy8yAAAUkAAAAE8AAABgaGyBu2NtYXAAABTgAAABlAAAAkQkRATXY3Z0IAAAFnQAAABeAAAAugDsQf1mcGdtAAAW1AAABZcAAAvNb3/BHGdhc3AAABxsAAAACAAAAAgAAAAQZ2x5ZgAAHHQAAEApAAB3CtbiupxoZWFkAABcoAAAADYAAAA2BkubWWhoZWEAAFzYAAAAIAAAACQHFARfaG10eAAAXPgAAAI6AAAEEk4TN4Nsb2NhAABfNAAAAhIAAAISiLhpam1heHAAAGFIAAAAIAAAACACigzgbmFtZQAAYWgAAACUAAABHhQGLdJwb3N0AABh/AAAAq4AAASRk5y6n3ByZ...QxUajCCFt4p9HP4fzdSWs2XhWl5HvJazrIrFUyB0l5dpqcW10lV2wukjMLuAvyMHNiYpgPsrCVXZDKrkpll6UWkh7kABVAFVCDe7UFmxagDegA+hLHRPbqtMo7ZHCpKdT6tPGXybzo0+RXBLoPZt1tELcXxCmAAyZwYTJvdDFZKnDER44X2451rDqCyunIsRWvLSx6wnWqwPj/uX5/KuEy6DL0z6A/Fn79VihxMFJsrlAFy4DpZOcvNlMeNp+BRDLj0r+XFdRxdSNSNxiI/AL3ojKdAAB4AWPw3sFwIihiIyNjX+QGxp0cDBwMyQUbGdictkUwWDAwsDJogTgOPN4c9iz6bMos4iysHFChUDZXJnMWTSZZJrAQt9M+YQYBBh4GTgY2kEZOoJiA0z4GBxiEiDEzuGxUYewIjNjg0BGxkTnFZaMaiLeLo4GBkcWhIzkkAqQkEggceHw5HFkM2VRZJFlYebR2MP5v3cDSu5GJwWUDW9xG1hQXAFAmKZU=' because it violates the following Content Security Policy directive: "default-src 'self' https://*.stripe.com". Note that 'font-src' was not explicitly set, so 'default-src' is used as a fallback.

I'm on Chrome 72.0.3626.96 (Official Build) (64-bit) for MacOs Mojave on a 15" Retina Macbook.

I went ahead and disabled my adblock and other extensions on the page but that did nothing. I also checked other sites to see if I see a similar error but its only on your site. :(

Woah this is crazy! What page are you on? As far as I know, I'm not base64'ing any fonts!

Dude this is crazy. If you can open devtools and nail down exactly which part of the HTML is doing that, I would be grateful. I have never heard this complaint before, nor have I seen it a console, nor am I aware of anywhere in the app that I have fonts specified as a base64 string. Absolutely the only thing I can think of is a browser extension adding this to the DOM.

It was a browser extension. Took a bit to find it as I'm an idiot. :P

Grammarly's browser extension was the culprit. Sorry to have sent you on a wild goose-chase! haha

About to say, I was having the same thing - The Base 64 decodes to the "Akkurat" font. Didn't have the error incognito though. Crazy!

Figured it out by switching to incognito mode actually. Newly added extensions aren't enabled in incognito by default and I never enabled it there so it makes sense that it would not interfere. :)

Ah, Grammarly. All your writings are belong to us!

After hack after trust violation after lie, I made the decision to install no more extensions on any browser. Ad-blockers selling our browsing habits might have been the last one.

I don't even have my password manager's extension installed. And yes, it adds an extra keystroke to my login.


You can simply add "data:" to the relevant directive(s). That's what we do.


Amen. If there was any critical thinking going on in the web dev space, we would not have a node_modules directory that is multiple gigabytes for a webapp.


I think this is a pretty disrespectful, dishonest take. There are so many wonderful, thoughtful people in the OSS world who have helped build some remarkable tools. You're trashing their efforts in an offhand comment, and it undermines your point.

Ryan Dahl himself regrets a lot about Node.js, including the issues around the node_modules directory and iirc he even apologizes for it in this talk:


I've don't think there is any disrespect going on and I don't think trashing a solution is a transitive operation in regards to it's users. I'm very sure those wonderful people hate the node_modules melarky too, OR they have a higher tolerance for complexity, better at ignoring details OR they are rich enough to have a great computer with a fast internet connection, so they are impacted less by all this craziness...


Great write-up. Another thing I've found is if you're using a back-end framework, it comes with features you'd otherwise have to re-implement in a SPA, like authentication.

Nothing wrong with progressive enhancement - if the network supports it, and you can deliver a better experience, then load in some JavaScript, but I don't see how it should always be a necessity.


By authentication provided from a back-end framework you're referring to pre-made login user-flow templates, not a possibility of authentication implemented in the front-end right?


Spot on. So something like Laravel for instance. It'll set up the templates, migrations, and auth logic if you want it to.


Wow, <details>/<summary> is a lovely time-saver.


I feel like I'm missing something – what is <details> doing for you here?

HTML's <select> and <option> elements can't be styled because of this people use lots of JS to make inputs that work the same. You can, however, style <details> and <input type="radio"> elements to have the same functionality but be fully customisable by the creator.

Got it! Also I just realized you linked to a whole post about it, not just a JSFiddle for me to puzzle out on my own. Hi, I'm new here.

Sorry, I should have been clearer 🙂
Welcome to the community Erik.


Hi, Erik! I recently wrote about details and summary, trying to account for some of their uses, polyfill guidance and expectations for accessibility:



Honestly this comes as very opinionated, at least in the comments. You seem to equate the "JavaScript experience" as folders with GBs of files, when you can just pick this or that thing. You don't need to use create-react-app. You don't even need to use NPM if it really bothers you. You could serve pages from a server, bundle in React and let it handle all the DOM manipulation and that's it. React is pretty good at it. Write the rest in pure ES6, don't add in libraries since you probably won't need them for most stuff. What's the obsession with including everything but the kitchen sink?

You complain about how big Asana is, but is your software doing exactly what Asana is doing? Can you cover all its business needs just with HTML and CSS? Call this or that guy fool, but that guy might actually need the data to steer the company and deliver sensible informations. You might need to fit in a larger project where you can't call the shoots. You might need to deliver what is effectively a progressive web app that does stuff and not simply display a dumb form. Your users might hate how spartan your app is and just prefer the bells and whistles. You might want to avoid spinning a refresh to the page to make a call just to show a error because the server is busy - and puff the user's work is gone. You might want to add in real time capabilities. Handle complex states. Undo and redo. Integrate a chat system.

I can go on and on and on. It's great that HTML and CSS are super useful (they are). It's also great that I can pick my tools, avoid the framework nightmare (if I want) or adopt it if I need a coherent system to bootstrap a complex application (if I want, of course). Being scared of complexity is just as bad as putting in too much complexity because "you might need it later"; what all projects need is a clear scope and business requirements, not jihads. You might find that "you don't need this" may just break a company's workflow for no good reason.


I personally have no obsession with including everything but the kitchen sink, but if you spend any time with real SPA codebases out in production at real companies you will find that is the case.

Of course certain use cases cannot be achieved without JavaScript (see the part where I said I had to use it to implement drag-and-drop). Of course Asana could not be built without JavaScript. But 27MB to load a task manager is asinine. My conclusion is not "you can do everything without JavaScript" but rather "make sure your reasons for using JavaScript are legitimate." My app is well featured, fast to load, fast to execute, yet not overengineered by a team of 50. Coincidence?

This absolutely is an opinionated post because I'm extremely tired of slow to load, slow to execute, and often buggy software! Apollo 11 made it to the moon with 1MHz and 4KB of RAM. There is absolutely no fucking excuse for typing plain text in an input to lag on my computer with each character.

If you're not scared of complexity the fantasy will end soon enough.


This. Best. Ever.

Atom says, "Hey look! We built a text-editor with coding formatting and colors.... in a web browser! Woo-hoo!"

There are people who say, "Let's make games in HTML5!". And the consoles still sell and every teenage son of mine doesn't even know what an HTML5 game is or why they'd play one.

It's a web browser. It's built to... wait for it.... browse the web!

I still marvel that people go to Gmail.com to check their email. It was a neat trick ten years ago. I didn't think people would seriously manage their businesses that way. Every once in a while people see my native Apple Mail app (PC users, usually) and ask about it. "What website is that?".... what the?


The main point is, there's a lot that is not either right or wrong in Information Technology. You can be considerate of users and also have a great experience - the two things just aren't mutually exclusive. You seem to be assuming a lot about what goes on in any team that is working on a frontend product.

I'm currently working on a project that matured from recognizing the limits of server-side applications for example. My users are tired of having to refresh to fetch data, tired of not knowing what is really going on or just end up waiting without a reason, and most definitely want drag&drop, instant previews, offline capabilities and WYSIWYG. I can't walk up to them and say "well guys, nope, we're moving to something that is even less reactive than Wordpress" and not get immediately thrown rocks at.

Whatever rows your boat, I'm happy for you. I guess you live in a place where you can do whatever you want without any repercussion. I live in a place where I most definitely can't deliver a 2006 experience just because I feel entitled to burn my company time and money on my ideological wars about what they need or not need and call them lazy.

Perhaps we have different visions: you want me out of business, I'll read what you do and take note to improve my design. You're so sure the web is not for apps, I love that the web is the great equalizer where no one can tell you what you can or can't run. I'm not afraid of complexity, I'm afraid of what happens when people decide their own bias about tools are more important than a job well done. I shouldn't even call that complexity honestly, because there's no black magic behind React or anything. And if you find my 200 kilobytes to be too much, please, just download the fuckin' app and bye bye.

Wow, why so salty? Your rant makes zero sense and is completely irrelevant to this post. The author says:

"My conclusion is not "you can do everything without JavaScript" but rather "make sure your reasons for using JavaScript are legitimate." My app is well featured, fast to load, fast to execute, yet not overengineered by a team of 50. Coincidence?"

If you really need it, use JS. If you don't, as in the author's use case, then don't. The overall user experience of his app is awesome compared the simple approach it took to deliver it.

I also don't have a team of 50 to make my apps, yet I still deliver JavaScript shit. Coincidence? 🤷‍♂️


Exactly. Technologies are perfect, people who use them are not.


Amazing. Thank you for sharing your experience!

I have a question. Have you had to compromise with design? I guess the real question is did you have to rethink how the app works and did you make UX decisions based on your choice not to use JS much?

Sorry if it was asked before.


Yes, it affected the design very much! I encourage you to create an account and play with it (you can completely delete your account from the settings page if it's not for you).

I think there are a few things that would have normally been done without redirecting to an intermediate page. For example, when you create an invoice, you must first select the client to which this new invoice will belong. If it were a SPA, my initial reaction would be to bring up a modal or autocomplete-dropdown listing all your clients so that you can select one. However, since it's not a SPA, you are redirected to slimvoice.co/invoices/new which is a listing of your clients.

I somewhat dislike this multi-step process and I think that a modal or autocomplete-dropdown for selecting a client would make it feel less like a multi-step process. But at the end of the day, the app still works great and is fast, and I think once you get used to a little hiccup like that, it totally outweighs having a slow, heavy app.

Another thing I did to improve the UX was make sure that all inputs and buttons are disabled when you submit a form, so that you realize that it's submitting and don't try submitting twice or navigating away from the page.


You say that its easier to debug HTML than JS because of the advantages of an IDE. Why can't you apply these same advantages to your JS development. If you just install a linter you will find most errors before you even try running your code.

I like your website and it is very clean. However what if you had to build something like YouTube or Reddit? Do you honestly believe you could build a website with that level of complexity with just HTML/CSS in a reasonable amount of time.


I have built plenty of SPAs in the past, of course all using linters. Linters find typos, not logical errors, mishandled events, or actions gone awry.


Well if you are using VS code you can explore the marketplace for help.



I really really enjoyed reading the article, it is exactly what i feel at this time about frontend development. The amount of time to get a custom webpack build and a server side rendered Template together is too damn high.
Explaining this to colleagues who are not that experienced feels like having a excuse for not just embedding plain old javascript where possible. Its a hype train i just hopped on...

The whole beauty of simplicity is gone. I think its a kind of not knowing html and css enough what leads to this javascript hell.

I am at a early stage build for a ecommerce platform, which has a little interaction and server side templates. Now, after reading your article i want to throw away all kind of VueJS i have including this complex webpack sh*t 😫😁 So i think i should deeply considering these accidental complexity for its real benefits.

Thanks for that 👌😍


Love the use of Mithril when you did have to reach for JS tooling. It's the one framework that gets just about everything correct and is tiny (KBs rather than MBs). It is also my drop-in when I need to write something that cannot be done otherwise.


I didn't read all the comments so this might have already been said. You can do this little trick for input/labels. When you put the label below the input and then you can rely on the status of the input to display different things like requirements for the input if it is in an invalid state, etc. But then if you want the label to be above the input you just use flex and give your label an order of 0. This does require that you put your input/label in a div. But it is a small trade off.

I found intercoolerjs to be pretty good too. But I think you could probably do the same thing with less code and without jQuery to make it even more light weight.


I love this. And there are so many HTML elements that we could use that would obviate the need for Javascript, I hope this helps push that discussion forward.

E.g., we have an HTML datepicker now, but we're unable to easily style it. On Twitter a while ago Lea Verou (at least I think it was her?) advocated for a standardized autocompleting country dropdown, which sounds like a fantastic idea. We've been building web apps for over 20 years now, and at this stage there's a pretty rudimentary set of standard components, and we there are many for which having a styleable native component is long overdue.

And all of this doesn't even address accessibility, which almost always works better with native elements vs. Javascript-built components.

In fact, it sort of seems like most things that have role attributes for a11y (e.g., modal dialogs) should have their own HTML elements by now.


I just found out about the datepicker a few months ago. I was incredibly happy to ditch JS for that.


Actually you can use detail element to make modals, GitHub uses this approach to make thier modal without JS



Nice! I think I might migrate to that because the checkbox thing is such a hack.


Hello, I have looked at an invoice page code source. And I have a question : it appears you have a script tag with a JSON description of the invoice. How do you map this data to every invoice line input ? I thought it would be server generated !?
Great example of frugality, should always be a first choice way to do webapp.
Keep on this attitude.


The server renders the HTML page and inserts some simple JSON so that Mithril can pick up on the data and populate the drag-and-drop UI. When the invoice is sent or otherwise not editable, the server skips the JSON and Mithril is not used, so the server just renders the full HTML for the line items.


This is extremely interesting, many people are advocating "plain vanilla JS and no framework" but this goes a step further. And the end result looks great, I love the style and simplicity of the UI that you've created, looks & feels really refreshing.

I had to think right away of this article:


They do use some JS but just to enable AJAX and Turbolinks. This enables partial page updates (through AJAX, with the server sending HTML snippets e.g. to replace a "div" on the client). So no SPA or client side framework but also fewer full-page reloads.


Yeah exactly! Figure out where your application can't afford reloads and build for that when appropriate.

The whole attitude about page reloads "feel like dial up in the 90s" is a little over the edge: when I navigate between pages in Slimvoice there isn't even a white flash. If your server is efficient and you don't try to load insane gobs of data, it's not as big a deal as the SPA zealots make it out to be.

Pick the right tool for the job, not reaching for what everyone else is smoking today.


You're right, the pages changes in Slimvoice are barely noticeable, the UI feels slick and responsive, everything looks and feels lightweight.

If you need to scale it up to a more complex UI then you may want to utilize the AJAX/Turbolinks approach, but even then you'd do almost all of your programming server side (the tiny amount of JS is just to enable the AJAX/Turbolinks).

The biggest problem with this "new" (how funny that sounds) approach is that it requires a different skillset, there are now heaps of devs familar with React etc but comparatively few strong at core HTML and CSS (I'm also looking at myself, lol). So if this approach is to become popular then we'll need to "train and relearn".

On the other hand, React (and for instance Next.js which enables SSR) when done "right" can be just fine as a dev experience but what you see is that people tend to overcomplicate stuff. Redux, redux-thunk, sagas, behavior/presentational, patterns and again patterns, I can easily see that people get "JS fatigue", we're just busy with tech and not with business problems.

Other example: people throw in moment.js and lodash/underscore adding another how many KB extra download (and parsing/compiling) where most of that can be implemented using native JS and a few wrapper functions. Way too much baggage which gets added without thought.

On the other hand, the time people are wasting at setting up Webpack and Babel and whatnot should at some point become a thing of the past, this should be a matter of running a few commands from the terminal and after that forget about it. But maybe we're not there yet.

Anyway, yes this approach feels like a breath of fresh air.

In addition to making your pages much more lightweight and taking the complexity out of web dev there's also the huge reduction in boilerplate: with API + SPA you're programming a lot of things at least 2 times (on the server, and then on the client) - validation, passing data from a to b, redundancy and duplication everywhere.

What do you think about the upcoming Web Components standard? That might make it possible to vastly improve the "native" capabilities of HTML while remaining light on JS and framework agnostic.

By the way, you didn't put the code somewhere on Github? (I can imagine that you're protecting it as you're running a business on it)


this is beautiful, it encourages young budding front end developers like myself not to get caught up in knowing the latest JS framework to learn without getting a grasp of the html and css basics. This is really nice.


This is not a website made after a design. This a website made for a design.

Any scroll and needing an ajax action just to call something. For example ... a vote button. Or you know remembering what you typed in the last form without submitting.

This doesn't require javascript at all since it doesn't do anything besides... wait wait.

Validation of email, well not here. I need to complete everything after a fail(this could be resolved)... Oops?

Even the password vs confirmation doesn't work. I need to click submit ...

There are tons of problems that i don't expect from a signup in 2019...


I am a designer gone dev and I have to say how much I loved this article. Much like in the design world, many (especially on FE) are on the lookout for the coolest new tools, the neatest new trend etc etc...

This extra flair usually comes at the cost of a user in some way or another. Instead of just throwing everything you could download at your project, you were thoughtful (extremely so) to deliver a great spa.

Nice work.


Great write-up. I'm a big fan of HTML-first dev. There's a million and one things that can be done before needing to add JavaScript to the mix. My personal fav (after the use of :checked for modal interfaces) is (ab)using :target to make a SPA. Also, I love using css data- attribute matching to make a search box filter a list of results without JavaScript.

The only glaringly obvious thing that was missing from your write-up was the use of the HTML5 manifest caching option to help make your app work offline, and not need any downloads after the initial download. PWA eat your heart out!


Hi. I've read your comment. You mention using data- attribute to make a search box filter without JS. Where could I find an example of that technique? Thx


I think the problem is actually that everyone is so extreme on everything. Why does it have to go from huge bloated javascript to "javascript-free". Why does everything that people do these days have to be so extreme to one end or the other. Why can't it just be "Oh hey here's how you make your site faster and not terrible for people on terrible internet speeds" - i dunno, I get tired of the hype train, but also by the extremist anti-hype train just the same


"How I increased performance by 3%" doesn't get clicks. Everything on the hype train is so extreme that if one were to say "I did stuff in an old boring way" no one would pay attention. Any sort of reaction opposite to the direction of the hype train needs a level of force roughly equal to the hype train to be noticed.

The actual content of the article only extremist in the sense of wanting to provide an *extreme*ly good user experience. The conclusion at the end is clearly about critically evaluating the right tool for the job, not presenting the one and only correct way of doing things.


How bout...
"How to Convert your React sh💩show site into a performant user experience"
"How I increased performance by 99%"
(changed request size from 13mb to 6kb?)

Just saying - maybe i have an anti-js trigger, esp when the anti-SPA reason is "What if they dont have javascript turned on" - usually said by someone who has never tried to browse the web with js turned off.

All that said, - your actual effort and end result is respectable and very cool. Nothing I disagree with on execution, just ya know ... click baitiness :)
well done


Loved that article! In an era where JS is all the rage, with bloated websites that favor fancy animations and styles instead of the content, seeing something like where the user experience was actually put in first place makes me really happy.

Admittedly, I'm not a JS fan, and a firm believer that, if your site won't show the actual important content with JS disabled, it's not worth of my time. You made something that's quick, usable and accessible to almost anyone.

I appreciate your work a lot, thanks for setting a nice example.


This is a good read. I think the problem is, it takes actual work to do things "right" these days, and also companies can get too big to change the course of the ship in a different direction. People also like to do what they're comfortable with and what's subsequently easier and faster for them. I just like when people take the time to look at something differently like you have here—there is nothing wrong with server side calls, especially when done cleverly and with caching etc.


Oh. My. Goodness. Thank you for not only being a voice of reason, but for fighting back. With HTML guns! In the spirit of the famous quote, "the enemy of my enemy is my friend", and in full confession that for me, JavaScript is my enemy, I love you! As a friend!

I feel like I've been a voice in the wilderness. Does anyone under 35 have any clue what a Megabyte is anymore? I swear I'm going to round up the Angular/React crowd and force them to use a 80286 for a month. With floppy disks and no HD. (Quite honestly, they'll probably be more productive after a few weeks than anyone using Google Docs).

But you took it even farther. You actually built not just a website, but an app. Where is your alter so that I may come and worship?

I don't see how you are looking for work, but then again, I do. Someone hire this guy ASAP! Gee, all this noise about climate control this past week, but companies are hypocrites. 4Mb page downloads and busybee JS flying around and stinging every browser? How can you call yourself "green", BigGiantTechCompanies.

And Matt, when you get hired, take me with you. I'll just read the HTML spec all day (and CSS) and we can spend our days eliminating JS from every ridiculous slider and checkbox.

I thank my lucky stars I haven't bothered with any of those JS frameworks - or really much of JS itself. I always thought it was a temporary hack from 20 years ago until now. Sadly, I probably lost a lot of paid work as a result, but at least I can look in the mirror.

I'm excited about WASM and some of that stuff (being a fan of complied vs interpreted), but I fear that all the clutter, which might run faster, will just linger.

We don't need it. Follow Matt everyone and have him lead you to Nirvana. Or at least away from Div and Class hell. The fires are hot down there and the water is absent. Come to the HTML5/CSS3 river and be refreshed!

Who wants to rebuild WordPress without JS on the front end now? LOL... "Let's see... you want a lightweight CMS that everyone knows how to use (and I like Gutenberg, I must confess), and you want to build out your 6-page small business brochure-style site? Uh, you're gonna need Bootstrap and jQuery for that!" (says WP and 95% of the themes out there).... Sigh....


This is amazing! Thank you so much for sharing your process, I don't know lick about backend, but I can't wait to read more.


This is awesome! Thanks for the great write-up!

Why can't we have a standard search element that filters a list on the client side (similar to how ng-repeat | filter: worked on Angular 1)?

I believe you are looking for a datalist element:

<label for="myBrowser">Choose a browser from this list:</label>
<input list="browsers" id="myBrowser" name="myBrowser" />
<datalist id="browsers">
  <option value="Chrome">
  <option value="Firefox">
  <option value="Internet Explorer">
  <option value="Opera">
  <option value="Safari">
  <option value="Microsoft Edge">

The ability to do the modal/checkbox trick above without it feeling like a hack and writing weird CSS.

Totally agree. There is the not-fully-supported dialog element. But it still takes some js to show and hide.


I like the idea but feel the article is ignoring the target for this.
I think for a small app this is great and you can do without (or even use java or php) javascript, but for any business requirements you will eventually either need ES6 or a js framework to work with.

In terms of Bundles, I mostly work with Nuxt.js and can tell you my critical bundle is less than 150kb GZip along with all the ssr goodness and optimisation


You are tackling the wrong problems.It's not about refresh button or modularity, its about UI in sync with the State. PWA is not only about loading time, it's also about lesser bandwidth usage. I am assuming you're against local storage and web workers, since it's not HTML or CSS right? I agree with you on 1 thing. Initial loading time of JS frameworks are long, however it can be modified with SSR (server side rendering) and module preloading strategies.

JS frameworks were created to tackle the problems Facebook or Google had with their internal products, its wasn't meant to be used for simple blogs or pizzeria sites.


I was fully onboard with all of those benefits of SPAs when I started building them. It never works out in the real world though. "Less bandwidth" is sort of a bogus argument for a couple reasons:

  1. Asana requires 27MB to load first time, 13MB if your cache is primed. Using Slimvoice requires 42KB for your first load and roughly 8KB for every subsequent page load. That means, with some quick math, that you have to perform 1625 page loads/actions in a single session on Slimvoice to make up for the initial load of Asana. I would be surprised if a user did 20 things on Slimvoice over one session. The comparison is slightly apples to oranges but I think I've made my point.
  2. The benefits of all that have turned out to be more theoretical than practical. I'll let JimDabell speak for me here. I too live with a relatively garbage internet connection, and I have not yet encountered a SPA that reliably solves these problems from any size company. It appears that Facebook and Google haven't actually solved it yet.

Hey I like your style, and I don't mean your css. I'm totally there with you on high tailing it to the safety of an SSR. I had a SPA blow up in my face after it ceased to function on my client's older machines. I built a compromised setup that loads individual react bundles instead one massive glob and supplemented support with polyfills. The concept of throwing client side JavaScript out the window is enticing. A python back-end also looks appealing. Ultimately I have trust issues with JavaScript.


Wow! Good job, I honestly didn't think it was possible to create an SPA without (or barely any) JS. I'm just wondering if you made your SPA WCAIG accessible, if so did you run into some issues while using some css trickery?


It's not a SPA. It's multiple server pages. I know that the CSS stuff is kind of a hack. Fotis Papadogeorgopoulos posted some awesome accessibility feedback here, but I haven't done any official testing myself.


Oh ok, yeah that makes more sense, haha nonetheless great job on making an SPA-feeling multi server pages website.


Though I'm in the same boat with you, I will say that the one benefit of using frameworks, is getting a bunch of devs on the same page. You go into React or Angular or insert here and there's often some basics laid out.

I'm a lone coder though, so to the wind with it all! Always prefer rolling my own over downloading and adding a million bloated libraries.


I can't help but think again and again in gmail while reading your article and the comments. Gmail was the app that brought AJAX to full use, it opened a lot of eyes even when Microsoft Remote Scripting was invented a lot of time before. But the real reason for thinking in gmail is the three available versions:

  1. the one most of people use: gmail.com Full bloated, unoptimized, pretty slow...
  2. the old html version mail.google.com/mail/u/0/h (almost the same you predicate here and I agree with you)
  3. the mobile version mail.google.com/mail/mu/mp a nice compromise between full-bloated and html. It's the one I'm using because it's as fast as I need and because I can use keystrokes.

My ideal would be between 2 and 3. Mostly HTML but with the minimal javascript (no frameworks, of course) in order to make it more usable and to avoid full page reload. By the way... filamentgroup.com/lab/html-includes/ is a nice technique for getting "pieces" of the interface without the full reload and to improve the interaction.


I can't help but think again and again in gmail while reading your article and the comments. Gmail was the app that bring AJAX to full use, it opened a lot of eyes even when Microsoft Remote Scripting was invented a lot of time before. But the real reason for thinking in gmail is the three available versions:

  1. the one most people use: gmail.com Full bloated, unoptimized, pretty slow...
  2. the old html version mail.google.com/mail/u/0/h (almost the same you predicate here and I agree with you)
  3. the mobile version mail.google.com/mail/mu/mp a nice compromise between full-bloated and html. It's the one I'm using because it's as fast as I need and because I can use keystrokes.

My ideal would be between 2 and 3. Mostly HTML but with the minimal javascript (no frameworks, of course) in order to make it more usable and to avoid full page reload. By the way... filamentgroup.com/lab/html-includes/ is a nice technique for getting "pieces" of the interface without the full reload and to improve the interaction.


As a Junior Front-End Web Developer I really liked the idea of reducing/removing the used of javascript for a lesser and faster pageload.

But I am just starting my career and my current project is a SPA using the React framework.. I don't know my stand now, LOL!


Excellent...I'm agree developers arguing about how to use even without asking do i really need this?? For sure you can solve the half of the problems without any fancy stuff.


I completely agree. HTML, done right, is like making Automatic Escalators. Worse case, they're stairs. Making full server-side rendered HTML with the same code as backend, and logic is still hard to do. I've been able to prpperly control my code bundle sizes, and ´ogic layer to be re-usable at different runtime levels, yet using the same code possible. I'm using a monorepo, publish packages in Nexus, have them as dependencies from a Koa server, Nuxt.js with Server-Side Rendering, and Vue.js in client-Side.
It's possible. But need to setup lots of tooling.


wow this is awesome. i'm a java/spring boot developer but i haven't kept track with the advances in front-end frameworks. i'll be following this and see how i can apply this to a side project of mine. currently i use spring for the backend and thymeleaf/bootstrap/jquery for the frontend. it can be bit of a mess.


Works everywhere.

Nop wrong. details/summary tags are not supported on IE and Edge. You have to use a polyfill, hence JS.


I think he's more-so implying it fails gracefully, still delivery an adequate content-complete experience to the end-user. If you use details/summary in IE and Edge, the user is still provided all of the content placed in the marked up, the interaction of close/open state is just quietly omitted.


Worth remembering IE11 is the only version of IE still in support and isn't that widely used anymore, it's not that unheard of to say you don't support IE.

Also, Edge will soon move over to the blink engine which will give it the same support as chrome.


I think he means the content is still accessible. It won't function the same but it's still usable.


Absolutely love this post. It shows how easy things can be, and they definitely are if there is less JS.


What browser are you using? If you click it, it should take you to the help page. I haven't had time yet but on my todo list is make an overview of how it works with screenshots and stuff.


I love this article. Regarding the fuzzy logic, could this be replaced by a datalist? caniuse.com/#search=datalist


I'm afraid not. First, I don't think it operates on Levenshtein distance, which I required for my app (so that you could type "crme" and it would show "Chrome", which will be filtered if you typed the same thing in a datalist). Also, I'm not sure that the dropdown of options can be styled very well.


Is there github of your project or some similar demo?


I code a pen that learns the thoughts of the article and other articles from the web.


great thought experiment! one pitfall is if a page renders a lot of images, as that normally can be handled via a lazy approach (needing js). but rendering react on the server & never needing to hydrate it is a fun thing to think about.


Amen! I've been cooling my jets on the whole "thick client" approach to web app development. I'm trying to get away from overly complicated build tooling and all the headaches that go along with staying on the leading edge of the ES landscape.

In most cases, we're using sledgehammers to kill ants when we bring in all these heavy frameworks and making our lives harder and the user experience less enjoyable.

Thanks for taking the time and having the courage to write this post in the midst of the React/Redux + Webpack cowboying that's going on these days. You're on to something great!


This is awesome! I feel you 100%! :D

I prefer the "hybrid / old school" approach to building web apps, server-side rendered HTML sprinkled with just enough JS to make it a more enjoyable and polished experience.

The modern JS libraries play well with this approach, like Mithril or React, the SPA is not the only way I don't understand why people are hell bent on it


Alright, I have read the comments here and I will be the first to say it: I don't know enough/haven't done enough front-end work to go about this route. Really, I can work with any arcane framework you can name (I can look up examples, doc and get up to speed in no time!), and that is because I intuitively understand how many of work (Mainly, by working with other similar frameworks). This is too scary!


Your users will surely like white screens on every action which requires a request to server, right?


Good question! I was very afraid of that when I took this approach. However, when you click a button or navigate, the browser does not immediately wipe the screen. The existing page is still presented until it gets a certain amount of response from the server (I'm not exactly sure what this threshold is, maybe an expert can chime in here on exactly what point causes a white screen). Much to my pleasure and surprise, there are very few white flashes, if any, for me on Slimvoice. Try it!


Yeah. I've actually thought of building a UserVoice-like app fully without JS. Would be much more useful if it's backend was written in x86/ARM assembly instead of C/Go/Python. XD, but that's crazy and would turn out unmaintainable since it's kind of low-level, but no white flashes since the web server is fast'n'primitive! :D

Seriously, try Slimvoice. It's in Go but it's crazy fast (barring a slow internet connection on your end). There are no flashes for me.


Great article and great example with slimvoice. But in this project as I understood you are owner and developer, in bigger projects with many stakeholders it is much harder to control project size. Marketing department wants Google Analytics, Design department want super fancy animation on WebGL, DevOps department wants New Relic data collector and Management wants it ASAP, so you end up with Asana with 10Mb of code. At my previous job I've had a chance to implement very simple picture image editing frontend app to help office manage with some routine daily task, but such simple solutions are not valued by big companies, managers simply ignore simple ideas. On other hand SMB is right place to introduce such solutions.


That seems to be the way things end up, but does that make it right? A higher level manager/CTO/CEO who doesn't recognize this is a fool.


I hope you start a trend here, simpler web dev for all.


This is superb! I always set as a goal for my blog that most functionalities are still there when JavaScript is disabled. The input approach is really clever.


Just going to leave this here..
HTML does have some improvements for native support of certain functionality, JS is just growing faster due to the huge user base.


'See How It Works' button below the phone image does not work. Using Chrome v65 on centOS 7 on a 24" monitor.


Ooops! Forgot the <a> tag. Fixed. Thanks for letting me know.


Interesting! Looking forward to your follow-up posts! Keep up the great work!


I wonder how will you handle a simple date picker without JavaScript 🤔


<input type="date"> no javascript required.


Damn, I'm ashamed, never tried this one xD can you style the picker to match design requirements m


"Quick. Easy. No JavaScript. Works everywhere." Lies. Not supported in edge w3schools.com/tags/tag_details.asp


Won't be long now that MS is switching Edge to Chrome's backend.

We're all doing the best we can with fragmented-as-hell implementations of an insane standard.


Have a look at this old article: 'Client-side full-text search in CSS' (uses only a couple of lines of JS)



THIS is awesome. I really love the idea and it seems a very perfect fit for turbolinks and derivatives.


One reason for JS is to offload some processing at the client. Your server can do less.


Take a look at the next post in the series. My server is not busy even with Hacker News frontpage traffic.


wow you're site is f*!@ fast...

What your choice if you have to create a cms for content and multilingual sites?


That's very interesting, thanks a lot for sharing!


Why can't we have a standard search element that filters a list on the client side (similar to how ng-repeat | filter: worked on Angular 1)?

You, probably, look for a datalist tag.


Hi! first, thanks for share your experience, i have a question: the date input calendar feature was done with javascript too?


Okay but I gotta know how'd you do the mouse gesture phone background-offset on the homepage without JS?


One word: Blazor.

The future of web applications is going to be based on Web Assembly, and Blazor will be out in front. Full-stack C# sounds very good to me.

Death to JavaScript frameworks!


All I can say is that finally somebody gets it.

This thing is a work of art - I am so unbelievably impressed and pleased. Full credit to you. It's so fast too - whips the llama's ass.


Most web interfaces I develop follow a somewhat similar approach. I don't aim for having no JavaScript, but I do aim for the application being fully usable if none or only some of my libraries are loaded. It's not very hard, actually. Most people who say progressive enhancement is impossible clearly never seriously tried to figure it out and thus have no clue what they're talking about.

You're absolutely right in asking why there is no "native HTML" support for a lot of basic UI paradigms that have been around for decades (like drag-and-drop). There should be. Anyone who claims to advocate for better accessibility should be advocating for reasonable built-in implementations.

A lot of trends in modern front-end development seem to stem from job security concerns. Tools are often several orders of magnitude more complex than the problem they're solving. Attempts to demonstrate that complexity is not necessary (like this article) are often met with angry, biased nitpicking.

Some unsolicited advice:

Using a progressive AJAX library really helps to bridge some gaps in native HTML capabilities:


I generally try to avoid modals and dropdown menus altogether. They're more trouble than they're worth and they're not particularly "good" UI even if you do them perfectly.

code of conduct - report abuse