Why I completely removed React from my Django project
Oscar

Oscar @kurealnum

About: 18 y/o, full-stack web dev specializing in backend development, content creator, low level programmer (aka Rust and C enjoyer). nvim & arch user

Location:
United States, Virginia
Joined:
May 9, 2023

Why I completely removed React from my Django project

Publish Date: Dec 1 '23
38 45

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

Comments 45 total

  • José Pablo Ramírez Vargas
    José Pablo Ramírez VargasDec 1, 2023

    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.

    • Oscar
      OscarDec 3, 2023

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

    • FJones
      FJonesDec 3, 2023

      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.

      • José Pablo Ramírez Vargas
        José Pablo Ramírez VargasDec 3, 2023

        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?

  • Alex
    AlexDec 1, 2023

    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

  • Yousaf sahu
    Yousaf sahuDec 2, 2023

    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.

  • Ghaleb
    GhalebDec 2, 2023

    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.

    • Oscar
      OscarDec 3, 2023

      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.

  • Jan Peterka
    Jan PeterkaDec 2, 2023

    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.

  • James 'Dante' Midzi
    James 'Dante' MidziDec 2, 2023

    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

  • Fasilul Rahman
    Fasilul Rahman Dec 2, 2023

    as a beginner. I didn't get any points 🙄

    • José Pablo Ramírez Vargas
      José Pablo Ramírez VargasDec 3, 2023

      The most important lesson here for beginners is: Be very careful of the things you read. In my experience, the implication that TypeScript is bad is very toxic for beginners. TypeScript is the best thing that happened to JavaScript.

      • András Tóth
        András TóthDec 5, 2023

        The unspoken thing about TypeScript is that it mostly beefs up your IDE to a similar level of an IDE working with a normal, typed language. Most benefits must manifest inside the IDE for TS to be excellent.

        In my writing I really wish to promote the idea of "working with your IDE and not against it". You can write code that obfuscates relationships, so your IDE can no longer help you. You can obfuscate file imports, for instance, and when you rename a file imported like that, your code will inevitably break; a simple task of renaming a file that your IDE could be doing for you, will no longer be available. From that point on, you have to remember to update manually your obfuscated file imports.

        The broader idea of TypeScript therefore, is to work together with the tooling you have, to work a little extra so you can delegate a ton of work to them. People dismissing TS are also going to write "magic code" that would further erode the ability of your tooling to save you from yourself.

    • zbyso23
      zbyso23Dec 7, 2023

      dev.to is not best source, many many articles here are not-realy-articles (link to some tool for example) and no big moderation here. And many articles are writen by junior devs. Try books in 1st place, not this.

  • Ghaleb
    GhalebDec 2, 2023

    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.

  • Sufian mustafa
    Sufian mustafaDec 2, 2023

    Great Post~!

  • David Broadhurst
    David BroadhurstDec 2, 2023

    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

    • Oscar
      OscarDec 3, 2023

      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.

      • Jan Peterka
        Jan PeterkaDec 4, 2023

        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!

  • Eduard
    EduardDec 2, 2023

    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?

  • Smyja
    SmyjaDec 3, 2023

    Typescript is ridiculously slow

    • anscarlett
      anscarlettDec 6, 2023

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

  • momo
    momoDec 3, 2023

    I was close to start my project with react and Django, I'm skilled Django dev and i love Django I am pro at Jquery and pure html and react but when I read this I got disanointed of react because i really like react whatever i don't know use what to start my music site front end.(I don't like Htmx and I tried Vuejs but don't like) what can i use for that?

  • abet-v
    abet-vDec 4, 2023

    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.

  • Samuel
    SamuelDec 5, 2023

    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.

  • András Tóth
    András TóthDec 5, 2023

    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.

    • Rob
      RobDec 9, 2023

      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!

  • Michael Kochell
    Michael KochellDec 6, 2023

    What makes typescript types "not clean"?

  • Heinek Halwin
    Heinek HalwinDec 6, 2023

    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 !

  • eerk
    eerkDec 6, 2023

    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 ...

  • stevenharderjr
    stevenharderjrDec 6, 2023

    Django works fine as a backend for React, but if you use its “sweet templating system” you’re chaining yourself to Web 1.0

  • TechStudent10
    TechStudent10Dec 6, 2023

    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

  • Ismail Cherri
    Ismail CherriDec 6, 2023

    Languages and frameworks are just means to facilitate your job. Once they lose this ability, they become a hindrance regardless

  • Robert Kraig
    Robert KraigDec 7, 2023

    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).

  • Samaksh Khatri
    Samaksh KhatriDec 9, 2023

    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

  • Michael Kochell
    Michael KochellDec 10, 2023

    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.

  • Michael Kochell
    Michael KochellDec 14, 2023

    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 :)).

    • Michael Kochell
      Michael KochellDec 14, 2023

      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.

Add comment