Baseplate-Admin

Why I Switched From Svelte 5 to Htmx and Django

6 min read

svelte is the most popular framework ( or in 2021 that was the case ). There’s no debate over the fact that svelte does some things right.

Pros of svelte:

  • No virtual DOM
  • Less boilerplate
  • Truly reactive ( or it was before svelte 5 )

So if svelte is a bag of goodies, why move away from it?

Well I am glad you asked.

svelte 5 is a mess

svelte is not all sunshine and rainbows.

svelte 3-4 had the nicest API possible.

Take for example:

<script lang='ts'>"use strict";
let count = writable(0);
</script>

{$count}
<button on:click={
    ()=>$count++
}>click</button>

This became something like in svelte 5:

<script lang='ts'>"use strict";
let countRune = $state(0);
const count = {
    get value() {
        return countRune;
    },
    set value(v) {
        countRune = v;
    }
};
</script>
{count.value}

<button on:click={
    ()=>{
        count.value++
    }
}>Click</button>

See the problem? This is the route react took with their context api

This tweet from fireship sums it all up

Coming from react land, this gives me PTSD.

Some people might say, “But it’s opt out, if you dont like it you dont have to use it”.

To which I reply, ”Rich hinted that runes will be the default way moving forward

svelte lost its original vision, instead they are going for a different direction ( to which not sure i agree with )

Jamstack gets expensive

The data transfer between backend and frontend gets expensive relatively quickly.

We were using REST api to move data from backend to frontend. There’s a lot of redundant payload that moves from backend to frontend.

Take for example we send this data from one of our endpoints :

{
    "name":"Joe Smith",
    "first_name":"Joe",
    "middle_name":"",
    "last_name":"Smith"
}

But let’s say we use only Joe from the above example. We still need to send everything from backend.

When the payload gets large ( about 129kb ) from our backend on each request, it gets expensive.

svelte community is confused and possible diverted

Oh boy, where do we start.

For starters, projects like pelte popped up right after rich announced svelte 5.

Posts like these popped started appearing on reddit:

These indicate that a portion ( may be small ) shifted away from svelte after the announcement.

Authentication between SPA and decoupled backend is hard

For starters, if you have a django backend, you dont have a straightforward way to do authentication from backend and frontend.

You can do something like token authentication, but the problem rises with storing the token securely, then validating the token, …

The token can be stored securely ( specially if you use something like sveltekit ) but the process is cumbersome ( server side route, setting https only cookie from server ) and it takes time to set everything up. Minus point is you lose client side routing if you go with this route.

The ecosystem is brittle

The entire svelte ecosystem didn’t get that much mature even after 2-3 years. For example there’s nothing like mantine for svelte. Well skeleton exists but it’s a relatively young project with countless bugs.

There’s no good text editor ( that’s native ) for svelte. Posts like this echo this problem.

The move

So, why did I move to django?

For starters django does a whole lot of things right ( that’s a post for another day ).

Some benefits:

Our new stack:

  • htmx

    htmx

  • django

    django

  • tailwindcss

    tailwind

  • hyperscript

    hyperscript

Authentication

For django we can do something like:

{% if request.user.is_authenticated %}
    <!--Do something-->
{% endif %}

To do this in svelte I probably would have to show either a skeleton or a loading spinner

No node.js server in production

Doing everything in django means I don’t have to deal with node.js docker container, saving resources and improving efficiency

No fetching data from backend

We can return the html rendered by django, no need to fetch data back and forth.

welcome back {{ request.user }}

With hyperscript we can add event driven interactions

Take for example :

on hyperscript:change(url)
    if url !== '{{icon.href}}'
        put 'btn btn-icon relative w-[4vw] h-[4vw] border-none rounded-[0.75vw] p-0 !bg-transparent' into my.classList
        remove .hidden from <span/> in me
    else
        put 'btn btn-icon relative w-[4vw] h-[4vw] border-none rounded-[0.75vw] p-0 relative !bg-accent before:absolute before:-left-[0.15vw] before:z-10 before:h-[1.25vw] before:w-[0.25vw] before:rounded-full before:bg-primary-500' into my.classList
    end
on htmx:afterRequest
    add .blur-sm
    then wait 100ms
    send hyperscript:change(url:event.detail.pathInfo.responsePath) to <icon/> in <glider-container/>
    send hyperscript:change(url:event.detail.pathInfo.responsePath) to <button/> in <glider-container/>

This doesn’t look that great compared to svelte but, we can achieve the same functionality provided by svelte.

Conclusion

I had really hoped that svelte would be my last framework. But the way things are moving forward, I am currently unsure if this would be the case.

Having many ways to do the same thing is why perl died and react became a mess.

svelte should get their direction right ( they originally had the motto “Reactivity by Default” ), should that happen i will return to svelte.

Don’t get me wrong, I still do absolutely love the innovations brought by svelte ( that’s why my blog uses svelte ), it’s just that I am not gonna rely on svelte for my main project moving forward.


Baseplate-Admin

I’m Baseplate-Admin, a software engineer based in Middle of Nowhere.