10 ms·
Sharing types between React and a Typescript backend is great DX for developing both in parallel and I've not seen anything that comes close to being as enjoyab
by stuartjohnson12 2y ago
Sharing types between React and a Typescript backend is great DX for developing both in parallel and I've not seen anything that comes close to being as enjoyable. Being able to change the signature of an API endpoint and immediately having all places in the codebase where the change will cause problems flagged as type errors is wonderful. I went back to working with duplicated types across python/typescript on a contract project recently and it took me 5x longer to fix the downstream implications of signature changes.
- rednafi 2y agoMaybe that’s because you only know one language and focused on using that everywhere. I have worked at 2 of those named companies where people made conscious decisions of moving away from TS backend because JS is an awful language to be used for system critical things.
- epolanski 2y agoCare to expand? I've been writing backend TypeScript for 8 years and it's more than fine. It's not my favorite language but it's a great compromise, and I would never choose a Lisp, Haskell, Java or C over it (the other languages I know).
- eknkc 2y agoI’ve been writing JS and then TS on the backend since 2013. Built large apps, startups and while it does the job fine I’d not go with Js on the backend anymore. We built some stuff with Go and then went with full .Net. Its like fresh air after years of Js.
- auggierose 2y agoWhat exactly did you like better in .Net than in TypeScript?
- eknkc 2y ago- Proper static typing. This is not .net specific but bolting types on a dynamicly typed language only works to some degree. It also opens the gate to runtime type intospection such as generating OpenAPI definitions without any other input than the handler signatures themselves etc. This is handled fine by a full stack ts framework like next or nuxt and such but you are still trapped in that implementation. - Proper multithreading and performance story. Performance itself is not the most important thing when your app mostly waits on IO. However you still get to use thread pooled async in .net or parallel goroutines in go etc and they sometimes make a difference. - ASP.NET Core is fully feature packed and easy to work with. .net has a more cohesive ecosystem where tools, libraries, and frameworks are designed to work together seamlessly. In js runtimes, you often need to piece together different approaches and deal with compatibility issues. - Proper standard library. Both node.js stdlib and the js globals are really weak compared to what Go or .NET or Java etc provides you out of the box. I hate dealing with npm dependencies with a passion at this point and you can have minimal dependencies when the standard library is decent. There is also the fact that upgrading an npm package is a dice roll as you need to trust the semver or check update logs etc. At least with a static typed language you get to catch public api changes on your dependencies during compile time, not in runtime. - Linq is good, Linq expressions are great. I don't really love ORMs but I tend to use Entity Framework Core on top of low level SQL access in .NET. Makes life easier. I don't hate TypeScript though. I still use it on the frontend obviously and I'm fine with it but given the choices on backend, it does not make much sense for me anymore.
- rednafi 2y agoJavaScript, in general, is awful as a language in terms of design, and more astute people have wasted many words on this before me. It was originally designed for writing throwaway frontend code, but people liked it so much that they started using it to build their system architecture—only to realize it doesn’t work well for anything beyond glorified RPC backends. The type system is wishy-washy, and TypeScript needs a massive type space to compensate for it. Python is also dynamically typed, but it has a strongly typed system that saves you from runtime blowups. JavaScript doesn’t even properly blow up at runtime—you just get [object Object] or some random undefined error. TypeScript is a fantastic piece of engineering from the C# guy, but even they couldn’t fix all of JavaScript’s language-level blunders. Few people want to build mission-critical backends on a weakly typed language. The ecosystem is a mess, and things randomly break after a few days. My Python and Go apps from 2018 still work exactly as they did on day one. Go’s gorm and Python’s SQLAlchemy are the default ORMs that pretty much everyone uses. And how many ORMs does the JS ecosystem have? And let’s not even start with frontend frameworks—no one loves them two days later. The Next.js project I built yesterday is already showing 69 vulnerabilities. This sorry excuse of a language, coupled with terrible design and an indecisively childish community, makes it difficult to take seriously.
- epolanski 2y agoYou're throwing random things but you have failed to explain real world pains. By the way you can be extremely strict and safe in typescript, it's really up to the team using it, but you can encode virtually everything and have it fully type safe. Also, there's great tools like effect-ts if you're more functionally leaning.
- hot_gril 2y agoIf you really want to waste time on types, the bolted-on TS is never going to work as well as Golang where they're native. Maybe TS types are better than Python types is all.
- epolanski 2y agoGolang's type system is not as expressive as TypeScript's. It's fine to not know about the goods in the TypeScript ecosystem. Again, I recommend you checking libraries like effect-ts or effect/schema or even better trying them. https://effect.website/docs/getting-started/why-effect/ https://effect.website/docs/getting-started/why-effect/
- hot_gril 2y agoI know about 10 languages by now, and JS is one of the later ones I learned. Nah, it's the best at what it does. And if I drew a graph of every project that's moved from language A to B, it would have cycles.
- charrondev 2y agoThis is the nice if your only consumption of the frontend is first party. Alternatively you could go the openAPI route and declare your API as a spec with types for a client to consume and the endpoint to return. This works cross-language and gives you docs first. (Start from the docs, convert that to types, then implement).
- ljm 2y agoI just wish YAML wasn’t so unwieldy for that, especially given the overall complexity of the spec. I also thing that the tooling hasn’t kept the same pace as it has with graphql, where it’s easy to document your schema and the inspector makes it super easy to play with.
- DataOverload 2y agoYou can write/generate OpenAPI in JSON. There are also many GUIs out there
- logscore 2y agoYou can write OpenAPI in JSON, which can help a bit with encompassing the complex and frankly fractured ecosystem of OpenAPI. I have found that the tooling tends to have the problem of not knowing how to catch edge cases like webhooks, websockets, complex auth and additional logic beyond just an HTTP request. Many tools add layers of configuration and extension to work around these, but i feel it misses the mark. I'm building Borea.dev to solve this pain by keeping the source of truth in your OpenAPI doc and allowing for custom code implementations. We support Python rn, are building out generators for multiple other languages and we're open source :P hope it helps
- eknkc 2y agoI thought the same but recently we started using .net on backend and openapi to generate typed api clients for typescript. I mean the initial setup was 15 minutes longer than a full stack typescript app but I get to use .net on the backend and all the type safety on both sides.
- dcre 2y agoAt Oxide we use OpenAPI schemas generated from the server code to generate clients and it works quite well to produce the DX you describe despite different languages on server and client. OpenAPI has its frustrations, but it’s good enough. I like to say that the main value of GraphQL was never really in the dynamic queries (in many ways an anti-feature) but rather in having a nice typed spec that lets you generate typed clients. https://oxide-and-friends.transistor.fm/episodes/the-frontend-of-the-computer https://oxide-and-friends.transistor.fm/episodes/the-fronten...
- hot_gril 2y agoOpenAPI, protobuf, etc. There are a lot of options that don't even require TS.
- nicoburns 2y agoInterestingly (relevant to the linked article), you can also do this in Rust.
- abraxas 2y agoI'm quite dismayed to say that this has been a feature of any Java developer setup for the past 25 years. Yet hipsters threw it all in the garbage when node.js took off and are only now starting to approach feature parity with a 2002 JBuilder or Eclipse of the same era. Can I tell you about live debugging of an app server and hot reloads? Pretty wonderful stuff really. I can't believe how much knowledge, tooling and experience was thrown in the dumpster when Java was abandoned en masse by the younger generation of devs due to the rise of node.js. And if it weren't for Typescript the tooling would still likely suck.
- mooreds 2y agoGWT was an attempt to let you live in java land and also still get the (tremendous) benefits of deploying to the browser Javascript VM. We used it on a java backed project, but we were not building an SPA so didn't see all the benefits. I haven't used it for a long time, but it's still alive: https://www.gwtproject.org/ https://www.gwtproject.org/
- abraxas 2y agoThat's cool but I get a chuckle when I see server side html rendering being all the rage now and thinking to myself, should I tell the juniors about servlets, JSP and Struts?
- jfengel 2y agoIt still blows me away that we settled on JavaScript as a VM. It wasn't designed for that, and it took a superhuman effort to make it work well enough. I feel like there's an adjacent universe where the JVM lives in every browser and JS was a weird failed experiment. But it turned out that the browser was the universal UI everyone had waited for, and Java didn't connect to it while JS entrenched itself there. GWT was a glimpse of trying to send us to that universe, via a twisty back door. But it was never gonna happen.
- agumonkey 2y agothe client side java didn't last long, flash and js were more mechanically sympathetic on too many aspects (dev culture, user expectation about load time, cute visuals) but yeah js is a strange creature
- wongarsu 2y agoTypescript and Rust may be more similar in this regard than you think. Both languages are born out of the desire to make coding simpler by making a stronger, more expressive type system. Sure, the details differ: Rust has lifetimes and about 8 number types, Typescript is garbage collected and has about one number type. But the spirit is similar. Both the typescript ecosystem and the rust ecosystem love the idea of taking types and function signatures and providing them for downstream consumers. While I haven't gone too deep down this particular rabbit hole, if you build a Rust backend you can use function signatures and annotations to automatically build an OpenAPI specification for it. You can then consume that specification to automatically build a typescript client library, giving you an automatically updating Typescript interface to your Rust backend. Similarly, there are multiple projects to automatically provide python type hints for your Rust python extensions. None of them really production-ready yet, but this is something people are actively working on for quite a while
- logscore 2y agoTHis is very similar to what Oxide.computer has done. They wrote their own tooling to go from Rust API to spec to Rust and TS client. Very specific to their use case, but I think its the right approach. If something is wrong in the client, you probably generated a bad spec, and therefore something in the API is rotten and should be adjusted. Using the spec as an intermediate to know if upstream is bad, can be a great benchmark for developers. My co-founder and i have a long term goal of building an end to end tooling chain for OpenAPI to generate spec and clients/tests/docs under one roof. Its definitely far off in development, but think its where devs are moving
- whizzter 2y agoThis is where OpenAPI/Swagger shines, we use C# backends and with NSwag (built in now also I think) you get an online API-spec directly from the controller (and types) of the C# code. Only extra step is running a tool to download the swagger and produce auto-generated typescript definitions, otherwise the workflow is the same as shared code (Some projects are typescript on both ends but C# gives a ton of other benefits for backends).
- cjonas 2y agoMy recent experience with NSwag was really bad... It could only handle the simplest of jsonschema. We were trying to connect with a typescript API that had heavy use of union and product types. Maybe the problem was just that C# doesn't support algebraic typings?
- astrospective 2y agoThat would track, one of the few things I miss when writing c#. Instead you break out into interfaces as much as you can.
- whizzter 2y agoYeah, the C++/Java/C# family of type systems have obvious holes in them. There are various hacks/implementations for them but since they're not in the core they're not really expected to be supported by random tools either. Like mentioned, our regular pipe is C# producer (server) and TS consumer (client). Consuming services authored in Java,etc is usually not a problem either but the TS system definetly has a bunch of more cases that aren't easily mapped.
- lbreakjai 2y agoThis is what we do. We use kiota to generate clients within other C# services, and orval to generate a client in the frontend. We also run some basic checks against the openapi definition in branch, to detect breaking changes and whatnot.
- deleted 2y ago[deleted]
- lmm 2y ago> Sharing types between React and a Typescript backend is great DX for developing both in parallel and I've not seen anything that comes close to being as enjoyable. Being able to change the signature of an API endpoint and immediately having all places in the codebase where the change will cause problems flagged as type errors is wonderful. Have you ever seen Scala.js? Same language on the frontend and backend, in a way that actually feels first-class and real. Type system that's as powerful as Typescript but also sound. Full IDE functionality if you need it.
- pier25 2y agoYou can achieve that with OpenAPI using any backend language. There are tons of generators that can create a client with types from an OpenAPI spec. Not only to/from TS but also tons of other languages.
- rixed 2y agoThere are legions of languages that can be transpiled into JS. Use any of them both for back and front-end and suddenly, not only can you use the same types but also the same functions.
- ec109685 2y agoHow can you deploy a system where you are changing API types in a way that breaks the type checker? It seems like in almost all cases, you want to evolve in a forward compatible manner, with a very slow deprecation process.