DEV Community

Cover image for Why I completely removed React from my Django project
Oscar
Oscar

Posted on

Why I completely removed React from my Django project

Yesterday, I completely removed any trace of React (and Typescript) from a project that I’ve been working on for a while (Non-Profit Link). But why?

It’s probably easier to tell you why I wanted to use React in the first place, and why those reasons were half of the motivation for me to remove React: Scalability, reusability, and, embarrassingly enough, just to be able to say that I’ve used React in a larger project.

Scalability ↗

Admittedly, I was a little bit hyper focused on the potential scalability of React. The components, strongly typed languages (as long as you’re using TypeScript, of course), and the overall neatness of it.

Well, lesson learned. Just because something can be scalable doesn’t mean it’s good for you or your project. Components are awesome, but only when you really need them. TypeScript was cool, but overall slow and obnoxious to work with (just in terms of this project, I still love strongly typed languages).

For example, this is just for a singular img element in a component!

export interface imgsInfo {
  img: string;
  alt: string;
  link?: string;
}
Enter fullscreen mode Exit fullscreen mode

And yes, React is neat and tidy, but that’s just more to manage.

Reusability ♻

Components are reusable, right? Right???

Image description

Sure, but that just means more files. More imports to manage. More things to make TypeScript lose its religion. More interfaces and props. Being able to reuse stuff is nice, but I simply didn’t need this amount of reusability.

“I used React with Django!” 📄

That’s what I wanted to be able to say, at least. But again, lesson learned. Just use what’s best for your project. Don’t worry about what might look good on a resume.

The other half of the “Why” ❓

Not to place the blame entirely on React, as I was the one who was absolutely starstruck by the ✨ scalability ✨ of React, however those features that I just mentioned were part of React. So, while I would like to completely blame React, that just wouldn’t be fair.

But anyways, onto what I was solely at fault for.

Django and React don’t like each other 🐊

Getting Django and React to play nice is like throwing a crocodile into a cage with a gorilla, and then telling them to shake hands and discuss the current economic situation of the world. They just won’t, and there’s no way to make them peacefully work together.

So what do I mean by that, in the context of Django and React?

The Two Options 🤔

I should first clarify what my two options with Django and React were. Either completely separate the frontend and backend, and communicate to the frontend through the Django Rest Framework (DRF), or use a bundler like Webpack to bundle your JavaScript (TypeScript, in this case), then load the JavaScript into each template.

The problem with using the DRF is that you get none of the advantages that come with Django.

For example, Django comes with a pretty sweet templating system. Without explaining it in depth, if you want to pass data from the server to the client, you can simply pass context to the template when you render it. In case you’re curious, it looks like this:

views.py:

return render(request, "index.html", context={"test": "test"})
Enter fullscreen mode Exit fullscreen mode

index.html:

{{ test }}
Enter fullscreen mode Exit fullscreen mode

Ignoring the imports in views.py, and the header info in index.html, it’s a grand total of (roughly) 2 lines!

Django also comes with user authentication, session management, and more. All the good stuff that makes development go quickly and smoothly.

I decided that if using the DRF removes all of the good stuff about Django, I don’t want to use it. So, I decided to use a bundler.

The bundler (i.e, the main issue) 🧵

This sounds like a pretty good setup, right? Well, I thought so, and I was incredibly wrong!

I could try and describe to you why this doesn’t work all that well, or I could just give you an example. So, let me show you what adding one <h1> element to a template named index.html would look like:

Add a div to index.html like so:

<div id="react-header"></div>
Enter fullscreen mode Exit fullscreen mode

Then, go to assets/pages/index.tsx. Import any components that you need to make the header (in this case, none), then write this code to render HTML in the specified div:

ReactDOM.createRoot(document.getElementById("react-header")!).render(
  <React.StrictMode>
    <h1></h1>
  </React.StrictMode>
);
Enter fullscreen mode Exit fullscreen mode

Ok, we're done now, right?

Wrong. Now you need to transpile and bundle this code with Webpack (this took about 10 hours to get set up):

npm run dev
Enter fullscreen mode Exit fullscreen mode

Webpack is kind of nice, as it does the transpiling and bundling all in one go, but it's still a pain.

Bundling can take anywhere from 1 second to 7 seconds (or more), and then, and only then can you see a <h1> element appear in the rendered template.

By the way, before you do any of this, you would also need to create and then work out the inevitable little problems with these files: webpack.config.js, tsconfig.json, declarations.d.ts, and .eslintrc.cjs.

As you can see, this is… incredibly painful, tedious, and overall, not a great idea.

So I removed React. Contrary to how long I thought it would take, it actually only took about 3 hours. And it was definitely a good decision.

Moving forward ⏩

As I learned, you shouldn’t just use something because it’s intended to work well, and you certainly shouldn't use something just so you can say that you used it.

Please do check out what the codebase looked like before and after I removed React. You can compare the differences here (commit before the removal of React) and here (commit after the removal of React). And guess what? The site functions just as it did with React, with at least 30 fewer files.

If I need a lot of functionality in the future, I’ll probably look into something like HTMX or Alpine.js. Otherwise, raw HTML, CSS, and JS are plenty sufficient.

What do you think I should’ve done differently, if anything?

Contact me:
oscar.gaske.cs@gmail.com
Github

Top comments (45)

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

The point of taking time to write TypeScript types is maintainability. Imagine this scenario: I just joined your project. I clone the repo and start playing with it. Without the types, where do I go look for, well, the types? Which properties does the data carry? Did you document this elsewhere? Probably not. TypeScript is your friend.

Collapse
 
lnahrf profile image
Lev Nahar

Typescript is a “transpilation”-time type checker. It can certainly be annoying or slow (probably both) to work with.

I do, however support d.ts files which can help you notate types in a Javascript project.

Collapse
 
viiik profile image
Eduard

I think one of the most common issues is changes / refactorings. Change a function to take an extra parameter; how do you know you updated all the call sites? Even ctrl+f / grep can fail if you take into account indirect calls.

This is just an example, another is returning json from a database query. How are you sure the columns comply with the endpoint schema? Maybe an update made a field nullable?

Collapse
 
smyja profile image
Smyja

Typescript is ridiculously slow

Thread Thread
 
anscarlett profile image
anscarlett

Typescript slowing down a Django project is really not the problem...

Thread Thread
 
ozzythegiant profile image
Oziel Perez

Yeah it's a skill issue

Collapse
 
fjones profile image
FJones

TypeScript is your friend for types, sure. But how often do you actually have ambiguous parameters where the exact type matters? Especially when using it with React. The fix for this shouldn't be dev overhead in writing more elaborate code-as-documentation. It should be writing clean and concise documentation, and sorting out parameter naming such that it tells you what you need.

Collapse
 
webjose profile image
José Pablo Ramírez Vargas • Edited

ambiguous parameters where the exact type matters

Unsure about what you mean by this.

It should be writing clean and concise documentation

So you believe exchanging TypeScript, a concise and precise method of "documenting" as you say, that can be parsed by a computer, that can be used in CI/CD to catch errors and that can be used by IDE's for code completion and faster development, with some MS Word or Markdown README file that computers cannot parse or understand, that cannot help with CI/CD and that IDE's cannot use to help you write accurate, error-free code is in fact the better choice?

Collapse
 
kurealnum profile image
Oscar

I certainly see your point on bigger projects. I think my overarching issue was that TypeScript was just unneeded in the first place.

Collapse
 
ghamadi profile image
Ghaleb • Edited

TypeScript is a God-send for application development, and you won't appreciate that until you work on a decently large enough project (it doesn't have to be too large even).

Types are extremely useful for maintainability and scalability. Ditching typed languages just because working with an untyped system is faster/easier tends to bite you back later.

Also, I didn't understand your arguments against React. If you want Django's templating system then why are you even considering any frontend framework at all? Frontend frameworks and a templating system of any backend framework are mutually exclusive.

The same goes for reusable the reusable components argument. React (or any framework) doesn't force you to break your components into reusable chunks. If your project is small enough that large components are better than reusable chunks, then work accordingly.

I honestly struggled to see any fact-based reasoning here. This seems 100% a preference thing. You don't like TypeScript, and you like Django's templating system.

Collapse
 
kurealnum profile image
Oscar

It's not that I don't like TypeScript, it's that I failed to see that it was not a good fit for my project. As you pointed out, types are extremely useful. But that level of "scalability", so to speak, is just unnecessary for a project as small as mine (and with no plan to grow to a much larger size).

Also, there really shouldn't be any fact-based reasoning in the first place; the only true "facts" present in my post is the fact that React has reusable components, and that Django and React don't play well together (and even that's a bit of an opinion).

Overall, it's just been a learning experience for me. Don't use the stuff you don't need, and put some thought into what that stuff is going to do for you in the long run.

Collapse
 
lnahrf profile image
Lev Nahar

I found Typescript to be worse in bigger projects, mostly because developers turn every, single, file to a type enumeration file. Type here, type there, it's a mess. I do agree with your point about React.

Collapse
 
ghamadi profile image
Ghaleb • Edited

What makes type declarations a mess I don't get it? Why is a type messy and an object not?

Types extremely help with the navigation inside a codebase. You can trace a type to all its usages, and if you mess up in one of your usages you get an error and won't need to go on a wild hunt to find that bug where you misspelled a property.

You can know the output of a function you haven't seen in 6 months by hovering over it, not by reading its code.

Without types you have to document everything. JSDocs are fine if you like them, but you haven't seen mess until you looked at JSDocs everywhere. And you have a messy codebase if you neither have types nor documenting comments.

Collapse
 
kwnaidoo profile image
Kevin Naidoo • Edited

Nice article. I agree. TypeScript is just a mess in my opinion - sure it's better than JavaScript, but there are better languages Like C# and Golang which handles types a lot cleaner. Even PHP types are much cleaner than TypeScript.

There are certain times that you need React, and I've built projects that are complex UIs, however most apps you can use Django templates just fine, and bring in HTMX or Alpine.js to add reactivity. (There's also Django Unicorn).

Collapse
 
latobibor profile image
András Tóth

If we could have had some C# in the browser we would have had some C# in the browser. Typesafe languages are the victims of the browser wars.

In case you have to go interactive you are going to end up with JS and if you had to go with JS you would use Typescript. It's not an "end-all" language as the design limitations of JS express themselves in TS as well.

Collapse
 
rtbw profile image
Rob

You can have c# in the browser using blazor webassembly.

For all the hate Microsoft get, after using blazor server and blazor webassembly for multiple projects, I have to say I quite like it. I've quite a few juniors on the team, and I find it easier to work with them as there's less opportunity for them to do crazy things as long as you get them to stick to the recommended design patterns. JavaScript/React definitely makes consistency better than it used to be in the JavaScript world, but it's only half of the parcel. You still get people doing weird and wonderful things, and often the only way to protect these projects is to cover the whole codebase in excessive unit tests. The current state of JavaScript reminds me of PHP in it's heyday. It was a lot of people's first language and judging by the online codebase it showed!

Collapse
 
mickmister profile image
Michael Kochell

What makes typescript types "not clean"?

Collapse
 
kwnaidoo profile image
Kevin Naidoo • Edited

In Django, you don't type every variable, instead, you type complex objects like database tables as classes. Python also supports type hinting, however, it's not mandatory.

So essentially you write less code and type where necessary.

The benefit is the code looks cleaner on a quick scan from top to bottom, it's easy to understand what's happening in the code. Whereas in TypeScript - I've seen large types being declared at the beginning of the file and it's more verbose, making the code less easy to read.

Using SOLID principles, more specifically the "Single Responsibility Principle" - your functions and classes can be easily unit/integration tested and you going to write unit tests anyway. So essentially this will catch any silly incorrectly typed variable or typing issues.

I guess it also comes down to the developer, and how you structure your code. I see a lot of TypeScript code where type definitions and other implementation logic are in the same file. Django by default forces you into MVT - so you separate your type definitions better.

Thread Thread
 
mickmister profile image
Michael Kochell • Edited

Whereas in TypeScript - I've seen large types being declared at the beginning of the file and it's more verbose, making the code less easy to read.
I see a lot of TypeScript code where type definitions and other implementation logic are in the same file.

This seems to be the only parts of your response that tried to address my question (not trying to be snarky, was genuinely curious what is bad about typescript because I like it a lot). I thought you were referring to the syntax of typescript itself.

You can define types at the bottom of a file if you want. There's no limitation to typescript there (I would prefer them to be defined at the top if they are going to be defined in the same file). So it seems maybe you have a problem with the way you've seen it used. I would recommend putting types in their own separate file anyway, especially if it's used throughout the application. Still wondering what exactly is "not clean", focusing on the nature of typescript types rather than mostly just describing an arbitrary alternative (python/Django). Django is amazing at what it does. It's a great framework and has a powerful ORM (much better and more mature than ORMs in JS land) and overall web framework, but you're kind of comparing apples to oranges here.

IMO the syntax of typescript types is quite clean. Only when you need to declare very complex types does it potentially become difficult to read, though these sort of complex types are sometimes not even possible to declare in other languages because of the level of complexity required. In that sense, typescript is very flexible. The only thing I would say about typescript types that is "not clean" are the error messages for type errors can be pretty gnarly if you are working with large types with many layers. The end of the error message usually summarizes what you're looking for though.

Also, I agree that separation of concerns and automated tests are important to having a maintainable codebase, but I think it's a bit orthogonal to the discussion on "not clean" types. Hopefully that makes sense. Every type system has its shortcomings, and none is perfectly "clean". But I happen to love typescript types. They click very well for me. I'd like to see it from your perspective as well.

Thread Thread
 
kwnaidoo profile image
Kevin Naidoo • Edited

Thanks for the detailed feedback.

There's nothing wrong with TypeScript - it's just a preference but also makes business sense. I don't see any benefit of TypeScript + React in most common applications, it just seems overly complicated for most use cases and junior developers seem to waste time-fighting with React and TypeScript.

HTMX or Alpine can do the same thing, with much less complexity. I do use TypeScript, now and then If I need to but I would much rather use C# Blazor if I were to build a large enterprise system rather than TypeScript.

For your regular run-of-the-mill SAAS or CRM or web apps, Django is just so productive and fast to develop with. That's my core focus - I want to ship products fast.

I don't want to waste time writing verbose TypeScript, that time is better spent writing tests.

There is no perfect system, all the major languages and frameworks are more or less similar. My point is - this is a topic about Django developers, so I say it in the context of someone who prefers Django.

TypeScript just feels weird and verbose compared to Python. So in that sense - I can't speak for all Django developers, but I would rather just write less frontend code in just normal JavaScript and keep all the heavy-lifting logic in Python.

Thread Thread
 
mickmister profile image
Michael Kochell

If the application is mostly server-side view driven, which is what the article is about and what you've been talking about, then indeed there will be very little javascript. I've been instead thinking in the framework of a heavy client-side application, because that's what I've spent most of my frontend work in, which is contrary to the article. Also, I'm biased because I heavily prefer a statically-typed language over a dynamically-typed one.

I was using rails at a previous job, and like Django applications you definitely want the server-side views to do the heavy lifting as you mention. Depending on how much javascript you need to write, I would feel good using javascript instead of typescript. As soon as I'm writing several functions that need to share some data type, I'm going to want to use typescript. But the application may not need that frontend complexity.

There is also the added build step of typescript that otherwise potentially needs no "building". I think this is the most inconvenient part of typescript. The coding experience, in my opinion, is immensely improved over javascript, though it really only becomes "required" (in my mind) when you start having multiple files doing things.

I'm also just used to reading a lot of typescript in general that it reads like english to me, which I imagine is how python is for you (which is literally much more like english, than js/ts :)).

Thread Thread
 
mickmister profile image
Michael Kochell

Also I'm curious if you typically write e2e tests or mainly unit tests, or any other kinds of tests. I try to make sure I prioritize e2e tests, to make sure I have coverage on many full happy paths of the application.

Thread Thread
 
kwnaidoo profile image
Kevin Naidoo

I use e2e and unit tests when I write them. To be honest, it's been a while because I'm more research focused these days, so I'm often experimenting with stuff that's emerging like transform models, hashed neural networks, and so forth. In those instances - BDD works nicely.

Collapse
 
yousaf11 profile image
Yousaf sahu • Edited

he Power of TypeScript Types for Maintainability: A Detailed Look
You're absolutely right! TypeScript types are incredibly valuable for maintaining code and ensuring a smooth developer experience. Imagine yourself joining a new project:

Without Types:

You clone the repo and start exploring the code.
You encounter a function called processUser(user) but have no idea what properties the user object contains.
You dig through the codebase, searching for clues about the user's structure.
You find mentions of properties like username, email, and age, but there's no guarantee these are all the properties.
You may encounter unexpected behavior or errors due to missing information about the data.
You might need to ask the original developers questions, potentially slowing down your progress.
With Types:

You clone the repo and instantly see that processUser expects a user object with clearly defined properties like username, email, and age.
You understand what data the function operates on, making it easier to write correct code.
You can navigate the codebase with confidence, knowing the structure of the data.
You can use IDE features like code completion and type checking to write faster and avoid errors.
The code is self-documenting, reducing the need for additional documentation.
New developers can onboard quickly and contribute to the project seamlessly.
Here's how TypeScript types specifically enhance maintainability:

Clarity: Types explicitly define the structure of data, making it clear what properties are available and what their values can be.
Improved tooling: IDEs can leverage types for advanced features like code completion, type checking, and refactoring, leading to faster and more reliable development.
Reduced runtime errors: Type checking catches errors early during development, preventing crashes and unexpected behavior.
Easier onboarding: New developers can quickly understand the codebase and its structure thanks to clear type annotations.
Safer code changes: Refactoring and code modifications are less likely to break functionality when types are present.
Better documentation: Types act as self-documenting code, reducing the need for additional documentation and comments.
Investing time in TypeScript types may seem like an overhead at first, but the long-term benefits for maintainability, developer experience, and code quality are undeniable. It's an investment that pays off in the long run, leading to a more robust and sustainable codebase.

Collapse
 
robertkraig profile image
Robert Kraig

I had a guy I worked with years ago.. The project was written in PHP, it was his first programing project that paid him $$$$. It was so heavily oriented towards everything is a function, rarely did the functions return values, alot of void methods passing references all around the place. Once I got into the project I realized I was in shitshow land. I told them we may gain more momentum rewriting this project by defining our table contracts / etc.. in a new framework. Go with something SPA based. I learned later that the product was used in the education industry & by many nonprofits which had computers often times so old that they didn't even work with modern javascript. I was pretty annoyed, and the product kinda fit the times -- sort of.

Moral of this story is, the best product is the one that works for you. Period.
If you're a single developer and you make headway without using React + webpack + etc tooling, then that is your way. If you make alot of progress using react + webpack + etc tooling, then bygolly, use that toolchain and make some cake. But lets not bully people for using what makes them productive, but we can call out their reasoning, and ask for some honesty. If you like something better than something else, just say it, and be like.. I was more productive this way, it reduced my cognitive overhead and I could sleep at nite and feel productive every time I added a new feature to my product.

Consequently though, if you release your product and feel like nobody is contributing to your project, there is a consequence to choosing to be less modern. It also means you'll have less contributors to your project, and maybe less young / green developers will be interested in learning the ways of old. So go and be productive in your old ways, just realize that sometimes people want their Tesla, and their Rust programing language (nothing wrong with rust).

Collapse
 
iamalexchip profile image
Alex

You could use something like inertiajs.com. It was built for Laravel but you hookup with any framework using adapter like this one for Django github.com/inertiajs/inertia-django

Collapse
 
harveyhalwin profile image
Heinek Halwin

Hi Oscar !
Nice post! I did the same thing a few years back, at the time, i was a django developer and python was my strong suit. I needed my application to have async refreshes in the FE, so instead of doing ajax and all that hardwork. I split the BE and FE, and adopted react for the frontend. This was perfect solution for me, while I wanted from django was the ORM tools and from React was the asynchronous capabilities.

Fast forward to 2023, I have adopted React (mainly Next.js with Typescript), so it might take some time to get used to JS frameworks. All the best !

Collapse
 
psypher1 profile image
James 'Dante' Midzi

Ah yes... I love this.

As someone who has used both Django and React in project when the premises of combining the two hit my radar I was very skeptical about it. As such, never tried to do it.

As for the comments praising Typescript, I've already written an article about that; so I'm not going to touch it

Collapse
 
skamansam profile image
Samuel

I've worked on some pretty big projects at several companies, and IMHO the easiest is to have your front-end and backends separate. You can deploy changes easier, especially if you have a lot of tests and a CI/CD pipeline. You can manage your team easier - front-end ppl on the front-end, etc. Even if you don't have the team, setting up DRF with token auth is a breeze and is easy to integrate with a standalone frontend. I agree auth is the big reason not to do this, especially if you have keycloak or another auth provider you are using. All in all, I recommend the separate apps over integrated apps, especially if you have a complicated front-end. If your front-end is simple enough though, you should totally go with your backend templating.

Collapse
 
dbroadhurst profile image
David Broadhurst

Yet another "I switched / moved from x to y". Here's some ideas to mull over.

  1. What framework / stack does the developer have the most experience with and can it be used for the project? Why add React in the first place? Sounded like you had stability / maintainability concerns with your current stack. Did those concerns get resolved when you removed React? Sounds like you decided the effort to use React wasn't worth it.

  2. How experienced is the developer. Learning curve for some concepts is just overkill for many projects. Complex ideas are useful when solving difficult problems but just add extra effort if they are just being used without any payoff

  3. What are you building? A basic HTML site or a highly interactive WebApp? Building a basic home page can be done with notepad and a basic understanding of html and css without any javascript.

All these types of articles boil down to the right tools for the project and developer

Collapse
 
kurealnum profile image
Oscar

You hit the nail on the head with your conclusion:

All these types of articles boil down to the right tools for the project and developer

React isn't bad. I'd love to use it in the future (with a codebase that's maybe a little bit more optimized for use with TypeScript/JSX). It just wasn't the right fit for me.

Collapse
 
janmpeterka profile image
Jan Peterka

For me, this type of articles is really nice way to see what other developers are really encountering in their journeys. It's not saying this tool is bad or _here are ten reasons why you should/n't use xyz _, it's just some small piece of experience.

I really like how you state reasons why you wanted to use React in the first place, and you just share how you found out it's not a good fit for your project (you + tools you want to use). Thanks for that, @kurealnum!

Collapse
 
eerk profile image
eerk

React was originally created to build "reactive UIs", in other words a system where the UI automatically updates all relevant components at the very moment the state of the application changes.

So if you can remove React without any consequences that means you indeed didn't need it in the first place ...

Collapse
 
abetv profile image
abet-v

I think you went the wrong way to try Django + React.
React is good for SPA or PWA, where you want to make real distinction between back & front. React works best with a restfull/graphql API.
So when you say "I decided that if using the DRF removes all of the good stuff about Django" thats the pain point, you have to give up on those in order to make sence.

Collapse
 
janmpeterka profile image
Jan Peterka

I really like using Hotwire/Turbo for my frontends (used in Flask project, which has nice integration, there's one for Django too, but it doesn't seem much active).

HTMX is pretty similar I guess.

So in my experience, when using something like Django for backend, you can do a lot with really simple frontend framework, no need to use "the big" ones.

There's a lot going on in this part of development - answers to "How can we create classic web apps, using the old standards of HTTP, and still having highly interactive pages?", making the development faster and easier.

I switched from Python/Flask to Ruby on Rails recenty, and this is one of reasons why - they are really invested in this.Turbo 8 is coming soon with automatic DOM morphing, which will further enhance the "SPA feel" for user, with classic backend development.
I really recommend looking into these (Hotwire/Turbo/HTMX/Stimulus Reflex/..), as I believe this is way forward for most classical CRUD web apps.

Collapse
 
techstudent10 profile image
TechStudent10

Webpack is absolute PAIN! I'd recommend using it 0% of the time and Vite 100% of the time. It takes milliseconds to transpile and it's overall better than Webpack. From a guy who moved to Vite from Webpack a couple months ago :D

Collapse
 
themightywolfie profile image
Samaksh Khatri

I recently had to work on a partially finished project which had Django + React (Typescript and bundled). I agree with you that most of the features Django were not being utilized. Not even the authentication framework, no models, no templates. I had to fix a lot of code.

In the end, I just ended up migrating from Django to FastAPI which was a lot more suitable for my use case