Moving off of TypeScript, 2.5M lines of code(engineering.usemotion.com)
engineering.usemotion.com
Moving off of TypeScript, 2.5M lines of code
https://engineering.usemotion.com/moving-off-of-typescript-e7bb1f3ad091
29 comments
I transitioned from Node to dotnet for backend last year and it's been great for APIs.
Love C#. Performance is fantastic. The framework and tooling are very mature (with exceptions like hot reload ugh). Entity Framework is amazing, by far the best ORM I've ever used.
I don't feel like an expert by any means but I'm productive. Some days I do hit some stuff that takes me longer that I would've hoped but I've been able to solve everything I've faced.
I only use it for APIs though. The fullstack stuff is not great. Maybe if Microsoft improved hot-reload I would consider Razor with a Vite setup. Blazor is just useless for me. It's very cool from a technical standpoint but your frontend is 10x slower and more bloated than the worst JS solution you can think of.
I connect my JS frontend layer with OpenAPI[1]. It's been ok but the whole OpenAPI experience is not as smooth as I had hoped.
[1] https://openapi-ts.dev/
Love C#. Performance is fantastic. The framework and tooling are very mature (with exceptions like hot reload ugh). Entity Framework is amazing, by far the best ORM I've ever used.
I don't feel like an expert by any means but I'm productive. Some days I do hit some stuff that takes me longer that I would've hoped but I've been able to solve everything I've faced.
I only use it for APIs though. The fullstack stuff is not great. Maybe if Microsoft improved hot-reload I would consider Razor with a Vite setup. Blazor is just useless for me. It's very cool from a technical standpoint but your frontend is 10x slower and more bloated than the worst JS solution you can think of.
I connect my JS frontend layer with OpenAPI[1]. It's been ok but the whole OpenAPI experience is not as smooth as I had hoped.
[1] https://openapi-ts.dev/
Are you experiencing any perf issues when using "Blazor Server"?
I benchmarked rendering performance with Razor Pages and it was fantastic. I'm assuming Blazor Server is probably good too as long as you're not using the wasm stuff. The dx on the other hand...
(just realized in my previous comment I didn't specify I meant Blazor with WASM)
(just realized in my previous comment I didn't specify I meant Blazor with WASM)
I really like C#, and I would generally vastly prefer it to NodeJS on the backend. I think one weakness is the library ecosystem, the competitors are stronger there. Most of the time this doesn't bother me as I also tend towards limiting dependencies in general.
There is a positive aspect to this, as it makes decisions easier as well. For many areas there is often a single good choice, there aren't dozens of web frameworks you have to evaluate. There's ASP.NET Core and then nothing else for a long time. And for the most part those are pretty good, so it does not feel limiting.
And C# doesn't have to be too enterprisy and over-abstracted. The community does tend a bit too much towards unnecessary abstractions in my opinion, but you don't have to use it that way.
There is a positive aspect to this, as it makes decisions easier as well. For many areas there is often a single good choice, there aren't dozens of web frameworks you have to evaluate. There's ASP.NET Core and then nothing else for a long time. And for the most part those are pretty good, so it does not feel limiting.
And C# doesn't have to be too enterprisy and over-abstracted. The community does tend a bit too much towards unnecessary abstractions in my opinion, but you don't have to use it that way.
> I think one weakness is the library ecosystem, the competitors are stronger there.
People say this but is it really the case? Look how much NPM has been attacked by malware recently, and all because people are indirectly installing simple colour libraries that are 20 layers deep of dependencies of dependencies. Then you get the fucking stupid stuff like `is-odd`.
People say this but is it really the case? Look how much NPM has been attacked by malware recently, and all because people are indirectly installing simple colour libraries that are 20 layers deep of dependencies of dependencies. Then you get the fucking stupid stuff like `is-odd`.
Long-time C# Dev here -- yeah I'm still jealous of being able to find more esoteric libraries in Node, Python or PHP -- or just having more options then someone's back-yard half-baked implementation sometimes.
On the other hand, I have nearly 20 languages under my belt and have been writing code professionally for 22 years -- I still use C# most of the time for a lot of other reasons, just this is one of the bigger pain points.
On the other hand, I have nearly 20 languages under my belt and have been writing code professionally for 22 years -- I still use C# most of the time for a lot of other reasons, just this is one of the bigger pain points.
We are (I mean I'm CTO & know C# better than most) but the only real downside is that there are a lot of people around Microsoft tech who are antithetical to startups.
You have to be absolutely insane and/or highly inexperienced to even consider Javascript/Typescript on the back-end. Not only is the language a terrible match but the deep architectural failings of NPM have been clear for at least a decade.
You have to be absolutely insane and/or highly inexperienced to even consider Javascript/Typescript on the back-end. Not only is the language a terrible match but the deep architectural failings of NPM have been clear for at least a decade.
Also, you can achieve some pretty fast development velocity with .NET. C# is intuitive and the tools are great. I know everyone complains about Visual Studio, but even it's most vocal complainers will admit it sets the industry standard for debugging.
One sticking point is that the tools, while community and small projects, are all behind a license. But, they are free for small teams making under something like $1M/year in revenue.
One sticking point is that the tools, while community and small projects, are all behind a license. But, they are free for small teams making under something like $1M/year in revenue.
If Visual Studio isn't to your liking then you can look at Rider or Visual Studio Code.
Rider should make anyone who is used to JetBrains' other products fairly happy.
Rider should make anyone who is used to JetBrains' other products fairly happy.
We build a Shopify-leading platform on C# at a startup -- they got so much flak from colleagues about it being built on C# instead of Node or Python.
Absolutely no reason other than "C# icky" -- they ended up with a platform that is crazy fast (and fast scales way easier, it handles a dumb amount of traffic without a lot of crazy design)
Startup culture is toxic AF at times, bad engineering decisions for cargo cult stuff.
Absolutely no reason other than "C# icky" -- they ended up with a platform that is crazy fast (and fast scales way easier, it handles a dumb amount of traffic without a lot of crazy design)
Startup culture is toxic AF at times, bad engineering decisions for cargo cult stuff.
I experience the same. When I try to have a rational dialog about trade offs, there’s nothing there. Or the “only runs in Windows” classic 10+ years outdated stuff
I’ve been writing C# on a Mac deploying on Linux for a decade.
I work at a .net shop and it is pain. Do not recommend.
I also work for a .NET shop and I absolutely love it. I'll happily work with .NET for the rest of my career.
It's very different in an Enterprise setting compared to a setting where it's being used by people who actually understand systems from logic gates up. The issues around .Net are in a lot of silly things people have been sold and an inertia of terrible frameworks if you're still in the full-fat-framework land.
TypeScript is generally a horrific language to use on the backend and especially for performance and even as a compiler. Just ask the TypeScript developers rewritting the TS compiler in Golang with all the problems they encountered using it.
C# is a much better choice to use for the backend and also a better designed language in general.
C# is a much better choice to use for the backend and also a better designed language in general.
They are close enough IMO that most devs can probably competently move between the two.
I think the big gains come from a more mature ecosystem of things that "just work". e.g. EFC vs Prisma or Drizzle with EFC having, for example, automatic change tracking and automatic up/down migrations.
The two NPM supply chain attacks this week also highlight another issue with the ecosystem in general.
We'll see how this change goes and evolves in Motion; C# is still relatively rare for startups, but at series C, it's no longer a seed stage startup and it increasingly feels like "it's just another distributed enterprise backend" (or at least it should be).
I think the big gains come from a more mature ecosystem of things that "just work". e.g. EFC vs Prisma or Drizzle with EFC having, for example, automatic change tracking and automatic up/down migrations.
The two NPM supply chain attacks this week also highlight another issue with the ecosystem in general.
We'll see how this change goes and evolves in Motion; C# is still relatively rare for startups, but at series C, it's no longer a seed stage startup and it increasingly feels like "it's just another distributed enterprise backend" (or at least it should be).
> In the end, I decided on C Sharp, even though I had never used it professionally
I love C#, I use it every day, but who makes a decision like this?
I love C#, I use it every day, but who makes a decision like this?
Great article!
.NET and C# are a great choice for web backend and CRUD apps.
With code becoming increasingly LLM generated, static typing improves evaluation of code compile time. So A+ for _type safe_ AI generated PRs :).
they seem to mean on the backend
Motion eng here: yes, this is a pure backend change; FE remains powered by React and TS with no plans to change it any time soon.
Main pain points with TS have become more obvious as the team grew and the codebase resulted in a multitude of different models representing the same thing.
- Prisma model representing the things (plural because Prisma generates a ton of variants for the different read/write scenarios) going in/out of the DB
- Zod models for OpenAPI generation
- Zod models for deserialization where we have `jsonb`
- DTO models at the boundary
- Additional front-end payload models that wrap the DTOs
A developer building a simple API endpoint do to a read will often up writing a handful of models for the same entity to move it back and forth...A lot of this work simply ends up being related to the loss of runtime types requiring a lot more modeling work creating a spaghetti of Zod and types.
Lots of papercuts in day-to-day and increasingly difficult to get otherwise competent engineers onboarded.
At least I'm not under the impression that this is a Silver Bullet. Will C# make it better? We'll see!
Main pain points with TS have become more obvious as the team grew and the codebase resulted in a multitude of different models representing the same thing.
- Prisma model representing the things (plural because Prisma generates a ton of variants for the different read/write scenarios) going in/out of the DB
- Zod models for OpenAPI generation
- Zod models for deserialization where we have `jsonb`
- DTO models at the boundary
- Additional front-end payload models that wrap the DTOs
A developer building a simple API endpoint do to a read will often up writing a handful of models for the same entity to move it back and forth...A lot of this work simply ends up being related to the loss of runtime types requiring a lot more modeling work creating a spaghetti of Zod and types.
Lots of papercuts in day-to-day and increasingly difficult to get otherwise competent engineers onboarded.
At least I'm not under the impression that this is a Silver Bullet. Will C# make it better? We'll see!
For basic CRUD like is emphasized in TFA you probably only need EF models to represent the db and DTOs to form the input/output contracts of the API. Many .Net shops (claim to) do DDD and will have an extra layer of domain models, but if you understand that your API is primarily CRUD they're just unnecessary complexity.
While you won't be able to share your back end models with the front end, OpenApi spec generation is pretty much automatic so you can generate the models or client code.
While you won't be able to share your back end models with the front end, OpenApi spec generation is pretty much automatic so you can generate the models or client code.
Yes; I think that's one thing that made this transition more sensible: we are not really sharing much of the BE with the FE and most of it is at the boundary already anyways.
After thinking for a year about my frontend choose; I decided to go with Razor-Pages + HTMX for all my new projects from now on.
What do you use for HTMX in Razor? any library or some manual plumpbinng? How do you disable layout?
I don’t know if you’re using this already but there are quite a few tools to autogenerate the typescript api clients from your backend code every time you build. Makes life super easy. You can also just do it in your CI/CD.
It looks to me team is clueless about database development.
Typescript ORMz lol.
Soft deletes make indexing, well, problmatic to say at least. Use temporal tabls instead for point in time recovery. Nevertheless it could have been solved on a database level without any help from ORMs, lookup RLS. Still, screws up indexing strategy.
Typescript ORMz lol.
Soft deletes make indexing, well, problmatic to say at least. Use temporal tabls instead for point in time recovery. Nevertheless it could have been solved on a database level without any help from ORMs, lookup RLS. Still, screws up indexing strategy.
In many cases, the bias comes down to perception — .NET is seen as “enterprise” or “legacy,” while in reality it’s open-source, cross-platform, and very well-supported by Microsoft and the community. For a startup that needs stability and performance without reinventing the wheel, .NET can be a huge win.