The reason NextJS and similar tech like SvelteKit are so popular amongst JS developers is that they alleviate the problem of Node.JS not having a great backend development experience. Building a backend in Typescript is like building it in C#, but without the advantages of a properly designed language. The experience of building a backend in Rails is miles away.
Node.JS developers are starting to realize it's not just about having the ecosystem and the tooling, it's also about the framework being a holistic solution to building out your application. That's what NextJS and SvelteKit help with, and that's what Rails revolutionized back in 2006.
Well it’s bolted on for a start so introduces overhead from the get go. Its type system is also severely hamstrung and complicated by JS compatibility. It doesn’t really compare to Rust, Swift, OCaml etc.
You say that, but its type system has some wonderful feature that those other languages lack. In what way is it hamstrung? It seems better than C# to me!
For example, C# doesn’t support parameterised enums like typescript and rust do. Once you start using parameterised enums, you seriously can’t go back. It’s a killer feature.
But even then, typescript goes further. All of these languages let me make a Color enum with red, green and blue variants. But as far as I know, only typescript will let me write a function which takes a strict subset of those variants. In typescript I can have a function that only accepts red or blue - and passing green (or something that might be green) would be a compilation error.
Typescript also lets you make another type with a superset of another type’s variants. Eg type Foo = Color | “yellow”.
In rust if I want to change a function’s signature to make one of the parameters optional, that’s a breaking api change since all existing callers need to wrap the parameter in Some(val). But in typescript, I just change the parameter’s type from T to T | null and everything works.
Again, in what way is it hamstring? I’ll grant that JavaScript doesn’t have quite the performance of C# (though modern runtimes are pretty impressive!). But typescript itself seems great.
> C# doesn’t support parameterised enums like typescript and rust do
To be fair, you rarely miss them with pattern matching and records. In a similar vein to a sibling comment:
var animal = ...
Console.WriteLine(animal switch {
Animal.Dog(_, var cats) => $"Chased {cats} cats",
Animal.Cat or Animal.Bat => "No cats chased",
_ => "Unknown animal"
});
abstract record Animal(string Name) {
public record Dog(string Name, int CatsChased): Animal(Name);
public record Cat(string Name): Animal(Name);
public record Bat(string Name): Animal(Name);
}
There are many libraries to further enhance the experience, provide additional exhaustiveness analysis, etc.
It's not an explicit feature, but a combination of arbitrary records, sum types, and type narrowing:
type Animal =
| { species: "dog", name: string, catsChased: number }
| { species: "cat", name: string }
const animal: Animal = ...
// Available in all cases
console.log(animal.name)
if (animal.species === "dog") {
// Can access dog attrs here
console.log(animal.catsChased)
}
// ERROR: catsChased only exists for dog and not for cat
animal.catsChased
While it is thoughtfully designed, its type system has been designed under the severe constraint that it must be retrofittable on typical JavaScript code.
> Your comment doesn’t advance the conversation in any way.
That's oddly rude. I thought it might be useful to someone (not necessarily you) to bring up the fact that TypeScript is subject to a very different pressure than most other mainstream languages. That has obviously resulted in a very different type system, e.g., one with much better support for structural typing than most mainstream languages.
> It just restates the claim that typescript is worse in some unspecified way.
I did not "restate that claim". In fact, I was careful not to claim that TypeScript is "worse" than any other language, because that's a meaningless word without more context.
> Can you give any examples of ways in which those constraints have resulted in a worse language?
Again, saying that it's "worse" or "better" without context is meaningless.
> That's what NextJS and SvelteKit help with, and that's what Rails revolutionized back in 2006.
Are you seriously comparing "being able to execute code on the backend" with Rails? Or Django? Or Laravel?
There's no way in this world Next/Remix/etc are helping in any way to write code on the backend. Where's the support for database access? migrations? ORM? queues? scheduled jobs? validations? translations? authentication? authorization?
The only thing Next.js is helping with is pushing people towards Vercel's platform, that's it.
Node.JS developers are starting to realize it's not just about having the ecosystem and the tooling, it's also about the framework being a holistic solution to building out your application. That's what NextJS and SvelteKit help with, and that's what Rails revolutionized back in 2006.