Turbopack, the successor to Webpack
vercel.com
vercel.com
Parcel is plenty fast and is pretty much zero config, I can use it to build libraries[2] as well as applications[3] for the browser and node.
I am manly building client side react applications, so your mileage may vary.
Make a T-Shirt with this and get rich.
Thankfully, Node and browsers slowly converge, so isomorphic code is less and less of an issue.
Btw, how does HN develop solo-dev apps? Do you switch between two projects? Run two separate webpack configs simultaneously? How do you share code/typedefs/dtos between them? Do you use or want to use backend HMR? Backend webpack-like import extensions?
got tired of creating and maintaining hundreds of lines of webpack.config.js files, I wanted something that just works
When I finally built my perfect set of webpack configs, I deleted them after a couple of months. This complexity is “fun” to set up, but maintaining it is not something I want not working as a “devops” full time. Achievement unlocked, so to the trash it goes.
I also recommend installing ts-node and writing your configs in Typescript to avoid typos
Here's an old side project of mine that has 3 targets [1]. I personally don't think it's that complex but it does have hundreds of lines altogether.
[1] https://github.com/Trinovantes/MAL-Cover-CSS/tree/master/bui...
https://m.youtube.com/watch?v=oCiGjrpGk4A
but more importantly, I recommend embracing the frontend-backend separation. it's important in desktop contexts too. after all, you don't want to block the UI thread with waiting for I/O, right?
of course the last ~2 decades were about coming up with various hacks, workarounds, solutions to make the whole threshold easier to pass (from Java applets to Ajax/XHR, comet/long-poll, websockets, server sent events, localstorage, WebSQL, WASM, service workers, and so on), but the basic architectural separation of concerns remains.
...
regarding sharing things between frontend and backend: OpenAPI + openapi-generator; monorepo works okay in VSCode, etc.
many people opt for RoR-like frameworks where they don't have to write frontend JS if they can avoid it (see also htmx)
Anyway, I’m looking for a tool that could make this part of development simpler by joining all these efforts in a “project and process manager” way instead of maintaining multiple toolkits/configs or generators. The latter I know how to do. Been there, done that, fed up.
this boundary is inherent in client-server software/systems/applications, there's just no avoiding it. every other API is basically unimportant and arbitrary.
the whole Web paradigm, the fact of "you need to download the site and run it" and the consequences and trade offs that it implies are basically unavoidable.
> Anyway, I’m looking for a tool that could make this part of development simpler by joining all these efforts in a “project and process manager” way instead of maintaining multiple toolkits/configs or generators. The latter I know how to do. Been there, done that, fed up.
completely understandable, and we're in total agreement. I also think that this is an underserved problem.
It's ridiculous that we still don't have near-perfect abstractions for these.
Well, frontend-to-backend api is also unimportant and arbitrary, unless it’s designed for public use. Since for a user the page is always in sync with its server, this api is an implementation detail as much as any other internal api (e.g. between service processes or between async-threads)
Why do you think that the project separation is unavoidable in this case? E.g. some of my sites are simple express apps serving scripts and resources. I don’t have integrated build pipelines there because… well, that is exactly my concern. There seems to be no reason that we couldn’t have an ~isomorphic project with multiple entry points on multiple “ends” and a single build system for all of them.
For example if we don't use any client side JS, use only a templating system, it becomes easy to keep it one project.
Eg. there's NextJS, which is a bundle of React and a NodeJS backed in one project. (And while it provides a getStaticProps and other gimmicks it doesn't really do much to make client-server state sync seamless. I still have to manually write the /api stuff.)
I did create a proof of concept how this could be done in parcel https://github.com/mochicode/parcel-fullstack-poc.
The /src folder contains:
1. /api => backend
2. /app => react frontend
3. /shared => shared code
Once everything is installed, just run "npm start" and it will:
1. build and watch your src folder
2. react hmr/fast-refresh works
3. nodemon will reload your node server when things change
4. serve your react app on localhost:8000/frontend, currently hard coded, but I could also load this from the package.json file.
Not zero-config, but it almost gets you there.
The project is just a small server rendered web app (using Crystal) that I wanted to add papercss, trix, hotwire/stimulus and hotwire/turbo to (using yarn). Anyway, I never got it to output the css for papercss or the js for trix.
Webpack on the other hand, I had working in about 20min. Yeah, the config is verbose and tedious, but at least there are a lot of great docs/tutorials for just about everything for it.
I could see that it won't be the right tool for a multi page server rendered app.
You'll still need to keep tsc around for that, though perhaps you're doing that with another step in Webpack...?
Let's say you have a tsconfig.json. Create a tsconfig-test.json like this:
{
"compilerOptions": {
"noEmit": true,
"skipLibCheck": true
},
"extends": "./tsconfig.json",
"include": ["./\*/*.ts", "./\*/*.d.ts"]
}
Add a script to your package.json (I use "test-types") ...
"scripts": {
"test-types": "tsc --project ./tsconfig-test.json",
...
Then you can "yarn test-types" quickly. I use husky[1] to run that command as a git pre-commit hook. My team cannot commit Typescript errors. Additionally I have a strict tsconfig and a strict eslint config (with these plugins:sonarjs, @typescript-eslint, simple-import-sort) which prevents "any" types and bad typescript hygiene. Results in faster code reviews.The lack of tsc in the new process made me wonder if it just got added to Webpack
You just have your tsc compile as a pre-commit git hook and CI pipeline step.
EDIT: The responses pointed out that the author is the maintainer of webpack, I removed that part of the comment calling it deceptive. Maybe the entire intent is to deprecate webpack. I still think that it should be renamed to "Turbopack: our webpack successor" because calling it 'the' successor is a bit presumptuous and the article doesn't even directly say that.
https://iamturns.com/typescript-babel/
and someone else pointed out that esbuild drops typechecking.
This is my point, that's what I'm doing. Webpack does the typechecking and the bundling together, you don't get broken bundles when the typecheck didn't succeed (unless you really want to, you can configure that too).
>and someone else pointed out that esbuild drops typechecking.
yes I know, these "faster" bundlers all drop typechecking which results in these unfair comparisons. Then I always end up spending a somewhat large amount of time checking these tools out only to realize that they are not doing a fair comparison.
ah, I do TDD. easier to let tests give me runtime and behavioral feedback instead of refreshing/setting up hot reloads. I could see how it's frustrating without that. super frustrating to do a quick experiment/demo and satisfy ts if the compiler breaks all the time tho.
the ts compiler doesn't break though, I think if I understand you correctly then this might be a relict of javascript-tier thinking/workflow. You're saying that you don't want to deal with the typechecks sometimes, that's not how any other language works. You're essentially saying that you want a build that silently works anyway because you know better than typescript, you know this will still result in correct js even though the compiler is shouting errors at you.
I think this is not the right way to look at this, if this is really a very common usecase then Typescript has failed to make truly useful optional typing. Which is actually something I've believed from the start, I was always perplexed when they claimed to be javascript compatible when that doesn't seem to be true at all, you cannot actually genuinely mix pure untyped js and ts code and have it all work seamlessly together. It always complains about adding any types and so on.
negative. I use tsc as a safety net, I don't release code that doesn't pass ci/cd which includes a linting/typechecking step. I just know that sometimes it's faster/easier to do an exploration without strict typechecking.
All that aside, it seems like Turbopack was literally developed with Webpack's maintainer, who claims it to be a "rust-powered successor to webpack" (his signature is quite literally on the homepage[0]).
maybe it is common, I can't speak to that but in my opinion a large part of the success of webpack was probably because they bundled the typechecking. Because that's the only workflow that makes sense, imagine a c# compiler that quickly outputs executable IL code but half the time it's broken because it didn't do any type checking and you have to wait for the IDE based type checker anyway. On every build. It just doesn't make sense to work this way, you never want a fast, silently broken build which is what you get with non-typechecked fast builds.
It's critical to run type checking outside of webpack. You should be able to execute code that does not type check correctly. It maximizes iteration speed and is one of TypeScript's key superpowers.
I'm genuinely curious here. How do you ensure contract correctness? The whole point of static typing (or rather explicit typing) is to declare and enforce certain contract constraints prior to writing [client] code, which prevents certain bugs.
What's the point of using type-safe language if you deliberately circumvent type safety? If you "fix type errors" by declaring things to be strings you do not get much more type safety from TS than plain JS.
Or am I hugely missing something here?
It helps to think of TS types as a guarantee of behavior and an encoding of intention, and of TS itself as a really smart linter. As long as you use my function according to these types, it'll behave as expected. If it doesn't, that's my problem and I'll fix it. If I say my function returns a string, you can use my function's return types as a string with the confidence that that's how I expected it to be used. TS will make sure that everything agrees with my type assertion, which removes the need for checking the types of parameters in tests, for example.
The typescript plugin that you used may have included type checking, but it very much depends on how you set it up. Many common setups use Babel to compile typescript code, which doesn't do any type checking at all, just mechanically strips away the type signatures. I would be very surprised if much of webpack's success has come from the type checking functionality you describe.
As for whether it's "the only workflow that makes sense", I find the most comfortable flow for me is using the compiler as a linter rather than a "true" compiler. It runs in my IDE, potentially as a pre-commit script, and in CI (which means checked in code cannot fail to type check), but I can still build failing code. This would be, as you say strange if I were using C#, but syntactically valid typescript can always be covered to syntactically valid javascript, so the output won't be "broken" in the same way that a C# program with invalid types would be. Most of the time, a program that isn't accepted by TSC is still a valid javascript program, just with poorly specified input and output types.
That said, while it can be useful occasionally if I'm still trying to figure out the types, the advantage here is less that I can now compile invalid code, and more that my bundler doesn't need to do unnecessary type checking. Any errors I can catch myself based on the red squiggles in my editor, so I know not to look at the browser until I've fixed all the issues, and at that point I don't need my bundler to also confirm that the types are accurate. Each tool does one task well. (Similarly, I don't want my bundler to also run all the unit tests before it compiles, even though I would normally expect the tests to be passing before I check the output of my code. 90% of the time, if I run the bundler, my tests are passing, and in the last 10%, I probably want to quickly try something out without changing the tests. The same logic usually applies to my types.)
As a result, I strongly disagree with the claim that your process is the only one that makes sense. It may be the most logical for you and your team, but I tend to find that it makes sense to approach typescript from a different angle to most typical compiled languages, and I've found a lot of success in my process.
How is it not a problem for you that you make a change in a .ts file and then you are immediately in a world of uncertainty: Is the typecheck already complete? No clear progress on this. The js output is probably already here, but not sure unless you constantly want to check yet another terminal window. So can I reload the page yet? Oh no wait, a few more type errors popped up after all, so I can't yet. This all happens in under 2 seconds but those 2 seconds are uncertainty and slow you down far more than any wait for a normal sized typescript project where typechecking is done integrated with the build.
I don't think that's it. I write pretty much exclusively typed code, except in places where I've not managed to get everything set up properly (mainly old Vue2 code). And even then, imports are unidirectional: JS can import TS, but TS can only import other TS files.
As to the "world of uncertainty", this lasts surely less than 100ms for me, certainly little enough time that it feels instantaneous. Usually I get feedback as I'm typing, sometimes if I'm doing things in new files I need to save the file first, but either way, my IDE is consistently fast enough that I know immediately if my code type checks or not. There is no downtime here at all.
As for seeing the code change, I usually have the page open on a second monitor, so I press "save", and glance over to my second monitor, and with live reload and a good configuration (that's harder to achieve on some projects, I grant you), I'm usually already looking at the results of my changes.
In practice, I very rarely have any uncertainty about what typescript thinks my types are - this information is always immediately at my fingertips. Where I do have uncertainty sometimes is whether the javascript types match the expected typescript ones - this often happens when I'm dealing with third-party libraries, particularly when `any` types start popping up. In that case, it's occasionally useful to ignore the type checker altogether, play around with some different cases, and then come back to ensuring that the types match later. That's just not really possible if you're treating the type checker and the compiler as an all-in-one unit.
right but livereload has the same problem as you: The build is already done so it reloads but lets say the typecheck will error out because surely you save a file more often than you want to recompile. So your page just reloaded which you didn't intend, in fact, it might actively have destroyed a debugging session which you didnt want to reload yet. How do you configure that away to make it work sensibly? And here is the kicker: I know you can configure your livereload build so it only reloads after the build and the typecheck are done. But this is precisely how we ended up discussing this.. now you always depend on both the typecheck and the build to end before you can test your change anyway.
I suspect we're just used to building code in very different ways. If you've not tried approaching typescript as a linter rather than "just" a compiler, I really recommend giving it a proper go - it feels very freeing, and I think is one of the biggest advantages of typescript as a tool/concept. (It obviously has its own disadvantages compared to how, say, a traditional AOT compiler would work, namely that tsc can never really take advantage of types at all during the compilation, but it gives you a lot of flexibility during development - essentially the best of both worlds for dynamic and static type systems.)
That said, if you've already tried it and know it's not for you, then fair enough - ultimately all of these tools are just ways for us to write code, so if you write code best in this way, then I don't want to try and force you to do it some other way!
You're right in saying that having a clean and understandable development environment has a lot of complicated moving parts! Dropping the ball on any one of them means having a bad developer experience.
Since I've said this on other comments, I'm not going to dwell on the fact that this behavior isn't something Webpack itself solves. However, if you make a change in a .ts file, two things typically happen in a dev server:
1. Your code is retranspiled and rebundled, usually using partial recompilation. 2. Your IDE sends these updates to the TS language server that powers your IDE's TypeScript support. That server uses the same typechecking logic as the TypeScript compiler, so it's a good source of truth for surfacing type errors in the files open in your IDE.
Depending on your dev environment, one of a few things might happen next: 1. Your dev server might hot reload the changes in your browser once the build is finished. 2. Your dev server might also block reloading if a type error is found. 3. Your dev server might even show you that error in your browser so that you know what's going on.
Next.js currently does all three of those things, which makes for a really nice developer experience. You don't really have to keep an eye on another terminal — everything shows up in your browser. They even render a little loading icon to let you know when a rebuild is taking place.
Next.js uses Webpack internally, but Webpack isn't the reason for this nice developer experience; it's just a core part of it, and is only responsible for bundling and rebuilding.
I love talking about this stuff, for what it's worth, so feel free to ask more questions. I helped Etsy adopt both Webpack and TypeScript when I worked there, so I have a good chunk of experience in the area.
https://blog.johnnyreilly.com/2017/09/07/typescript-webpack-...
Exciting news about turbopack - the world is about to get much faster!
Awesome!
> but half the time it's broken because it didn't do any type checking and you have to wait for the IDE based type checker anyway. On every build.
Huh? The IDE checks your types as you type. Not on every build.
This works great and de-duplicates effort. I have an extra "check" script that runs all the linters including the Typescript checker that you can run before making a PR or production build (tells you the same thing as the IDE). I'm glad it doesn't block my development build because it takes many seconds (10-20) while without it you can get updates in far below one. That's a night and day difference.
> you never want a fast, silently broken build which is what you get with non-typechecked fast builds.
You're misinformed about what I want. I want fast builds. Decoupling linting from building is a great way to achieve that. I am yet to experience any problems with it.
If you want to type check on every build you can put that into your pipeline, but it will unnecessarily slow things down. I for one am very happy with fast builds with no downside.
This is the point folks really must understand when setting up a new tooling pipeline to deal with TypeScript. Certainly all of the module bundlers I'm aware of operate in this way.
To explain further for anyone curious; for TSC to work effectively it must construct and understand the entire "compilation". To do this it starts by performing a glob match (according to your include/exlude rules) to find every TypeScript file within the project. Resolving and type checking the entire compilation every time the bundler calls for a transform on a file is very slow due to lots of repeated and unnecesssary work so most TS bundler plugins have to work around this. Unfortunately, they're still relatively slow so type checking and bundling code separately is often the best way to go.
Actually this painfully reminds me why I found it so weird that tsc doesn't simply offer bundling itself. Why wouldn't it? It should be very easy for the compiler to do this as it has all the information and on top of that, tsc also has an incremental mode already. That definitely means 'incremental' for type information.
If I remember correctly gulp(js) was perfectly able to do this.
but how do you do it? this is not as easy as it may seem. Of course it's possible but the value here is that I don't have to do this for every IDE and/or the LSP when I use webpack where waiting on the typecheck is an integrated feature.
I thought about it even more and I think I can finally see the possibly true reason why people are developing these type of bundlers: The typescript projects that they have to work on are so huge that the typechecking is always going to be too slow so you don't want to deal with it, you rather typecheck only the file that you're currently working on and you don't care about the 15000 other files because you didn't touch them since checkout and the reasonable assumption is that they will probably still work same as tested by some other team that worked on them and committed them. However there is still one large implication: Your production build on the CI server must then at least be configured to execute both the typechecking process and then the bundling process. I still wonder though: if the typechecking is truly too slow then wouldn't it also be too slow for your iterative development. I guess if those other sections of the code are never referenced then maybe it will do okay and you don't get squiggly lines on all your imports because it won't recheck them? I have some doubts that the typescript type checker actually caches this type of work.
It is also strange because somehow every other language in the world doesn't have to separate type checking from compilation, it's only in the js world that we somehow ended up with such large amounts of code that people felt that they want that speed back from back when js could simply be loaded into the browser instantly with no compilation.
And on top of that: If Turbopack does such supposedly excellent caching now, why would this not help with a 15000 file project and let me also do typechecking in a cached way? Yes I really don't think that omitting typechecking is the way to go for development.
That's why it's slow. It's also not a big deal because of parallel type checkers.
> Yes I really don't think that omitting typechecking is the way to go for development.
You've not really given a reason why. Just a rant about how other languages are different.
This is how the majority of people write typescript, and there is only upside from splitting out bundling and type-checking for these people.
Im a user of esbuild, and its so fast it can recompile on each save (see esbuild `serve` option) and i wont notice anything locally. Theres also a watch mode, and production build with minify.
So i work locally without a typecheck for my builds, and let my LSP client do the type checking. When i bundle for prod i run an additional tsc for type checks before the bundle is produced. Takes a few secs more (as tsc is slow) but this is a nonissue.
Your assumption (from your first comment) is that people only run bundling. That's not the case. People run bundling in parallel to type checking, rather than in series. You still get the type checking benefits without blocking your build on it and thus slowing down your dev process.
that was never my assumption
> why would anyone want only bundling
This is not a bigcorp thing. The Typescript compiler starts becoming annoyingly slow much earlier. I have a project that's one 2000-line TS file that already takes 1.5 seconds to compile. Not yet slow enough to be frustrating, but ridiculous for the amount of code.
Webpack was driving the typescript compilation and had some plugins/extra codegen steps to run too. I tried to move as much as possible to bazel but I quickly found out the JS ecosystem likes to produce massive balls of muds. Very hard to break down and separate the various steps.
Oh and if you create many smaller packages (as is best practice in bazel to get good cache efficiency and parallel builds) be prepared for nonexistent editor/IDE support.
Pure rollup is still the best for building libraries, by and large (maybe esbuild now? but I think rollup is more efficient in its output still).
If this has a good, solid library mode that works like rollup with the power of the webpack-like asset graph, it'd actually be amazing for the community as a whole.
I noted that esbuild doesn't fully support es5 transpilation and this will hold it back from some usage.
Plugins are the big differentiator between Webpack and existing "webpack but faster" tools, and presumably the reason most people still use webpack. What's the plan here?
"In future versions, we'll be supporting Vue and Svelte via plugins."
https://turbo.build/pack/docs/features/frameworks#vue-and-sv...
It sounds like plugins will be a thing but existing webpack plugins will need to be ported.
> We're planning on making Turbopack very flexible and extensible, but we're not planning 1:1 compatibility with Webpack … most Webpack plugins won't work out of the box with Turbopack. However, we're working on porting several of the most popular Webpack plugins to Turbopack.
https://turbo.build/pack/docs/features/frameworks#vue-and-sv...
When I say turbopack, I was thinking why the hell would someone need this. Vite is fast enough for everybody. Quite fast indeed. Then there is Parcel which is also quite good and reliable.
I never felt with Vite performance was an issue at all. Everything is so dang fast in my company's website. We are unnecessarily optimizing stuff!
Bummer! Do I need a turbopack.config.js?
I've still got my package.json, tsconfig.json, .env, and postcss.config.js apparently.
> [Turbopack cannot currently be configured with plugins. We plan to make Turbopack extensible, likely with an altered API]
Will I be able to use my current plugins? Where does config for these plugins live?
> [SCSS and LESS] don't currently work out-of-the-box with Turbopack
Keep it this way! LESS has been dead and SCSS dying. Focus on CSS Modules please!
`sass` (dart-sass) is the current iteration but it’s an order of magnitude slower for larger projects with many small scss module files. I’ve seen it add +10 to 30 seconds.
`sass-embedded` will be the next iteration for dart-sass but in its current form still suffers from similar issues.
I believe using postcss for nesting support + css variables is a better alternative, considering that css will likely get native nesting support in a few years.
Not for something that "scales to 100 teams", just something for me to spin an app up in quickly. i.e. 0 to 1 is the only thing that matters.
Next.js is just front end focused and has always left it up to the user to decide about data persistence.
So to answer the original question, an equivalent would be Next+Database, and there is obvious stand-out answer for what Database should be. I often get stuck deciding what that Something should be when trying to go from 0 to 1.
A DB is as simple as pressing a button on Planetscale or Railway, copying the secret strings to your .env file, and 'npx prisma db push'.
I have written Next apps that just connect directly to PostgreSQL, but I always end up adding other tools in an attempt to recreate something like ActiveModel and other aspects of Rails in Next.js, and it ends up turning into a mess. I think Rails+Next would avoid this problem. It would be two apps, but each would very clearly focused and would be built following the golden path of their respective frameworks. (One thing I’m not sure about yet is how I would DRYly share endpoint schemas from Rails in order to have strong typings in the Next app based on the API endpoints. But I don’t think it should be too hard to find a nice way to do this.)
I assume the mainstream is ready to swallow the idea.
Accordingly the docs and API and blogs are littered with a mish mash of all previous APIs.
Thats the whole problem with webpack-its always changing.
> We're planning on making Turbopack very flexible and extensible, but we're not planning 1:1 compatibility with Webpack. This lets us make choices which improve on Webpack's API, and let us optimize for speed and efficiency.
That aside, it is just so frustrating and sad that this just continues the fragmentation in the JS build space. It is beyond exhausting at this point. I don't care about vite vs (or with) esbuild vs turbo. I just wanna `script/build` or `yarn dev` and not think about it anymore.
It seems like collaboration and consolidation around common tooling is just impossible and not even considered a possibility at this point. We are forever stuck in this world of special snowflake build toolchains for damn near every app that wants to use modern JS.
The same problem plays out in the JS engine space (Deno raised $21M and Bun raised $7M) and in the framework space (e.g. Remix raised $3M). As long as there's money to be made and investors to fund projects, there won't be consolidation.
That reminds me, wasn't there a build tool called Snowflake?
Oh, it was called Snowpack [1]. And it's no longer being actively maintained. Yeesh.
I know Vite inherited the first part, but I still mostly disagree with Vite on switching the default of that last part: it always bundles Production builds and switching that off is tough. Bundling is already starting to feel like YAGNI for small-to-medium sized websites and web applications between modern browser ESM support, modern browser "ESM preload scanners", and ancient browser caching behaviors, even without HTTP/2 and HTTP/3 further reducing connection overhead to almost none.
But a lot of projects haven't noticed yet because the webpack default, the Create-React-App default, the Vite default, etc is still "always bundle production builds" and it isn't yet as obvious that you may not need it and we could maybe move on away from bundlers again on the web.
If they do not bundle for prod, then initial load will cause a flood of network request and cause slowness due to a lot of network requests
Plus, ESM modules always load asynchronously without DOM blocking so in any and all "progressive enhanced" sites and apps, it may feel slow to hydrate parts of it, but you generally aren't going to find a better performing experience while it hydrates. The page itself won't feel "slow" to the user because they can start reading/scrolling faster.
Some of it comes down to your framework, of course, and if you can afford SSR or are using a "progressive enhanced" style of site/application. For one specific counter-instance I'm aware of, Angular's NgModules dependency injection configuration mess routes around ESM's module loaders and creates giant spaghetti balls the browser thinks it needs to load all at once. I can't see recommending unbundling Angular apps any time soon as long as they continue to break the useful parts of ESM style loading with such spaghetti balls. Other frameworks, especially ones with good SSR support/progressive enhancement approaches are increasingly fine to start using unbundled ESM on the modern web.
The biggest issue in FOSS is folk don't wanna join a "good enough" project and move it. Sometimes the project is contributor hostile (rare?)
And we end up with basically: "I'll build my own moonbase with blackjack and hookers!"
All that starting from scratch costs loads of impossible-to- recover-time.
The world doesn’t need yet another JS bundler. It needs the one js bundler that works well with the wide variety of niche use cases.
It’s just not fun. And that’s one of the most important reasons I do this job.
Or start from scratch and make something better.
Either way, you split the community, but at least with the new tool you can (hopefully) manage to make it a lot better than a refactor would have been. (In some areas, anyways.)
Plus, this allows the old project to continue on without massive breaking changes, something its users probably appreciate. And this old project can still create new major versions if needed, which is something you don’t get if you have a major refactor because everything meaningful gets shipped to the refactored version.
So I think spinning off a new project is a net good here. It doesn’t impact webpack very much unless people ditch it and stop maintaining it (unlikely). It lets them iterate on new ideas without maintaining compatibility. (Good, when the big issue with webpack is its complexity.)
So if the idea turns out to be bad, we haven’t really lost anything.
Megalith? Isn't it super modular and configurable?
All the previous gen bundlers are written in JS and support a giant ecosystem of JS plugins. There’s no incremental way to migrate those projects to Rust. The benefit of these new bundlers is that they are literally full rewrites in a faster language without the cruft of a now mostly unnecessary plugin API.
And the “cost” of this? Some of these new bundlers are written by just 1 or 2 core contributors. Turns out with the benefit of hindsight you can make a much better implementation from scratch with far less resources than before.
It’s hard to overstate how game changing this new wave of zero-config, ultrafast rust bundlers are for the day-to-day dev experience.
This is an area where we could learn something from the Golang ecosystem. You're always going to end up with some warts in your API. Tools with warts that are consistent, documented, predictable, and long-lasting are so much easier to manage than tools that are constantly applying cosmetic revamps.
JS is not my main language, true, but damn it's hard to keep up. I think it took me less time to be productive with Typescript than with webpack.
Apparently rollup is used under the hood by Vite, and the plugins and config syntax are compatible, but I couldn't get my rollup config to work with Vite.
The build process is defined by the compiler (using Google Closure tooling under the hood) and has not significantly changed since the introduction of ClojureScript in 2011.
Since all CLJS projects use the same compiler, the build process works the same everywhere, regardless of which actual build program is being used (Leiningen, shadow-cljs, etc).
Moving away from Babel to SWC meant we could no longer use SCSS within JSX styled components. We first switched everything to plain CSS, which was a nightmare IMHO. Now slowly switching things to SCSS modules.
Now with Turbopack, we lose that too: https://turbo.build/pack/docs/features/css#scss-and-less
"These are likely to be available via plugins in the future." Fantastic
Whatever they got now though is just about perfect for me
There are some issues with realizing the potential though. Namely, a standard-ish CRA React app will have thousands of SCSS compilation entrypoints due to importing SCSS in individual component modules.
Lack of process reuse is causing many to see slightly SLOWER compile times. Next you have:
* Lack of tooling support: Vite?
* Need to migrate SCSS syntax
* ??
As soon as it's a free-ish upgrade with high ROI on swapping it in, I'll take it! I think SCSS is a dead-end though. Modern CSS + postcss for some CSS-Next polyfills is the way forward IMO.
I think it really depends on the use case. I use Webpack, but it's all configured for me by create-react-app and I don't have to mess with it. If my configuration could automatically be ported from Webpack to Turbopack and my builds got faster, great :)
Of course, that's not the only use case and I agree that speed alone won't decide the winner.
// @TODO implement and publish
import { webpackConfigTranslator as translate } from ”turbopack-webpack-compat”;
import webpackConfig from ”./webpack.config.js”;
const turbopackConfig = translate(webpackConfig);
export default turbopackConfig;
Any takers?I would add that esbuild has set the bar very high for documentation and configuration. I come away very impressed every time I need to touch esbuild, which is not usually my expectation when it comes to the JS build-and-bundle ecosystem.
And while vite is still young, it does a good job integrating itself with many different JS stacks. The docs are also great, and the project has incredible momentum.
Between esbuild and vite, I feel pretty set already. Turbopack will need to be that much better. Right now, it doesn’t look like much more than an attempt to expand the turborepo business model. Let’s see where they take it.
Parcel might be a good fit for you: https://parceljs.org/
On large applications Vite is fast to build, but loading your application in browser issues thousands of http requests, which is tragically slow.
Esbuild is basically instant to build, and instant to load on the same application. It’s a shame it doesn’t do hot reload.
If Turbopack can give us the best of both worlds, then that’s absolutely an improvement I want.
I believe there are areas for improvement here that Vite can make though. They need to implement finer grain browser side module caching, dependency sub-graph invalidation(Merkel tree?), and figure out how to push manifests and sub-manifests to the browser so it can pro-actively load everything without needing to parse every module in import order making network requests as it goes..
Lots to do lol.
This is one of the Rust things, we just have to build everything from scratch :).
Currently. I’m skeptical.
I'm curious about the "Cold Start" time for 30k modules taking 20s, which still doesn't feel like the best possible experience, even though it's a significant improvement over the other contenders listed.
Is there a separate, faster "Warm Start" time after everything is cached? Or is this it?
> Turbopack is built on Turbo: an open-source, incremental memoization framework for Rust. Turbo can cache the result of any function in the program. When the program is run again, functions won't re-run unless their inputs have changed. This granular architecture enables your program to skip large amounts of work, at the level of the function.
Which would make that multiple an extremely rough estimate, highly-dependent on the situation. But it's still an exciting development
And while Rust doesn't strictly enforce purity, it does make it a lot easier to stick to in practice with its explicit `mut` keyword for local variables, references, and function arguments (including for the `self` argument on methods). There are various ways like RefCell to get around this if you're really trying to, but you have to go out of your way.
And the article exclusively testing it against just Next.js build could be an indicator as of how optimized it is for the meta framework probably?
I think writing build tools for JavaScript in anything other than JavaScript (or language that compiles to js) is a dead end.
How would you write a plug-in to this? Or a programmatic configuration. So much gained from staying on js.
The advantage of having an incredibly fast build tool can already be seen with Vite and esbuild, which hot-reload modules at speed. Fast tools can change the way work is done.
And the github link at the top of the page links here: https://github.com/vercel/turbo but, despite being called "turbo", that seems to actually be the repo for Turbopack (the webpack alternative) not "Turbo" the library.
Even digging a bit into the crates, I'm not sure where this supposed library lives: https://github.com/vercel/turbo/tree/main/crates
A small example of code that uses this is https://github.com/vercel/turbo/blob/main/crates/turbo-tasks..., which defines how we can load a `.env` file using FS read caching, cached `read` and `read_all` functions, etc.
I just checked a code base that's at ~900 modules, and vite is ready to serve dev requests in well under a second.
If you reload the second time will be much faster since it will serve from it's memory cache.
I'm not trying to mislead... but it would be good to know what they are actually measuring.
Vite is indeed much faster than webpack, but they use this highly misleading "vite ready to serve in 100 ms" stat.
Combine next.js with https://blitzjs.com/ and you'll have something that looks like rails.
Looks like blitz is tRPC + next auth?
From what I understand Blitz is their own implementation of tRPC, their own Auth system, Prisma and Typescript support. Blitz is also more of a toolkit that wraps around NextJS currently, but later on Remix, Svelte and Vue.
In future (probably in '23 and post 1.0) some things that may be coming are:
- backend functionality ala NestJS
- form component library
- permissions (rbac) library
- file upload library
- and a bunch of other stuff I'm forgetting right now.
Blitz auth was developed at the same time as next auth, and takes a more imperative approach which allows you to build more custom auth flows.
There is currently a lot of cutting edge engineering focused on the Typescript ecosystem (Vercel, Cloudflare, Deno, etc) vastly outpacing things being done around Rails, Django, PHP, etc.
> Rome is designed to replace Babel, ESLint, webpack, Prettier, Jest, and others.
Since both projects are written in Rust, the Rome team could use Tubopack to build/bundle projects and focus on the other features they are planing: https://rome.tools/#supported-features
I tend not to trust architecture / quality / performance of people who made my programming life worse. :)
I get a lot of deno feels here. I'll just be happy with esbuild.
Why I wouldn’t choose, esbuild is because they don’t support the automatic React runtime and don’t seem to have plans to (or at least last time I checked.) Swc does… So as long as you’re okay with that limitation I imagine you’re probably fine.
You could also potentially use Bazel for remote caching in your rails app, though I haven’t used it myself so I don’t know how well it would work.
Not mentioning speed at all here, it was never my biggest concern.
Comparing an alpha just open-sourced today to an established tool like esbuild isn't even a fair comparison, for either tool.
The nice thing about Rails now is there's no massive direct integration like Webpacker once was. Now we can basically use the JS tool straight up and Rails will just look at assets in a specific directory, it doesn't matter what tool generated it.
https://twitter.com/ScriptedAlchemy/status/15850274824321802...
At least the marketing website is snazzy ¯\_(ツ)_/¯
I was also looking forward to Rome (a linter, formatter and bundler also built in Rust but still under development) [1] but looks like Vercel beat them to the punch.
[0] https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
There's this fairly recent notion that speed rules everything. Perhaps maintainability and releasing non-alpha quality software could have a day or two in the sun as well?
> There's this fairly recent notion that speed rules everything
Recent? I'd say it's very old, then got outdated as everyone moved to dynamic slow languages like Ruby (for Rails), Python (Django) and JS because of their perceived productivity improvements over typed languages like Java around 15 years ago. The pendulum is simply swinging in the other direction now.
And this behind-the-scenes-native code-but-pretending-to-be-Python is the reason why most Python stuff I try fails to run on the first tries.
Half of them I give up because I don't get them running after going down the weirdest error rabbit holes.
No matter whether Debian, Ubuntu, Windows 7/10, Cygwin, WSL2, Raspberry Pi, x64, ARM ...
> We're planning Turbopack as the successor to Webpack. In the future, we plan to give Turbopack all the tools needed to support your Webpack app.
> Currently, migrating to Turbopack from Webpack is not yet possible. In the future, we're planning to offer a smooth migration path for all Webpack users to join the Turbopack future.
I tried to explain that it was a completely different field, and that this was a web development framework. And that we had started ours way before this library for promises. But people told me I was foolish, and refused to look at it. I think it was here on HN somewhere around 2012 or so.
Well, promises are now native in browsers and no one remembers the Q library. But I did rename our library to "Qbix". I wish though that I hadn't listened to them... things come and go, just do name it what you like!
Regardless, I like that this is fast and it is probably going to get a lot of adoption since it will be included with Next.js.