29 ms·
Insights from Adopting TypeScript at Scale
- mgdev 6y agoI thought Bloomberg was into Bucklescript/ReasonML. Warring factions?!
- Scarbutt 6y agoCan't beat better ecosystem, better integration with the ecosystem and let other company(Microsoft) do the work for you.
- robpalmer 6y agoThe TypeScript ecosystem is amazing - partly because of the large number of users also also because of the sense of community. It is run as a true OSS project. Roadmaps are release plans are all public on GitHub. Even as outsiders we've been able to contribute significant features, e.g. Private Fields in TypeScript 3.8. https://devblogs.microsoft.com/typescript/announcing-typescript-3-8/#ecmascript-private-fields https://devblogs.microsoft.com/typescript/announcing-typescr...
- agustif 6y agoYeah TypeScript it's the only thing that makes me hate/doubt M$ a little less...
- robpalmer 6y agoWhat about VS Code?
- agustif 6y agoYeah I use VS Code, But yknow electron yadda yaddaa, I end up blowing it with too many plugins so it can be a little slow. Also the telemetry... Also although I love WSL for being able to use linux on my windows work machine, it is really slow for me. Trying to use a docker-magento image on windows under wsl gave me minute long page-loads. I also hit a bug the other day that would put my vps server at 100% CPU when working remotely with the VSCode ssh remote extension... So all in consideration, VS Code is Okay'ish but I'm not really a fan, for mac I like the new Nova editor from panic guys albeit it's newness that grants less community/plugins!
- mistersys 6y agoTypeScript was in the right place at the right time, and the team prioritized the right features in the beginning, allowing for the great adoption. But I'd still place TypeScript firmly in the "worse is better" category (products that are technically inferior then the state of the art, but succeed due to circumstance), it's a band aid on top of a the broken JS ecosystem. Its ad-hoc, Hodge-Podge type system and poor meta-programming is sad to see for such a popular language. I'd rather write TypeScript then JS, but as soon as there's an opportunity to write software that works across all platforms without dealing with JS, and with a type system that's actually built on a solid foundation, I'm taking it.
- munificent 6y ago> But I'd still place TypeScript firmly in the "worse is better" category (products that are technically inferior then the state of the art, but succeed due to circumstance), it's a band aid on top of a the broken JS ecosystem. I think it's important to distinguish between "worse is better" and path dependence, which is what you're getting at here. "Worse is better" is a blank slate design philosophy. It says a system with more failures modes can be a better than a more robust system if allowing those failure modes keeps the system significantly simpler and more understandable to users. A bicycle is "worse is better" compared to a car. You have to check the tire pressure frequently, and clean the chain fairly often. But it's easy to put air in the tires and you can see the chain and tell when it needs to be cleaned. "Path dependence" means your design is constrained by historical choices that don't benefit future users but are part of the reality you have to design for today. Train railway gauges today are not the best width for optimizing shipping efficiency. It was chosen in the 1800s before anyone really knew, and it's impossible to change because existing trains would be imcompatible with the new gauge. TypeScript is an example of path dependence. If the world didn't have a few billion lines of JavaScript code, you could certainly design a better language. Simpler, cleaner, easier to statically type, more efficient. But the world does have all that JS code, and TS is the railway that can still run those old trains.
- mistersys 6y agoYeah, I agree it was lazy of me define "worse is better" the way I did, I think they're 2 separate thoughts, but I still think TypeScript uses the "worse is better" approach to design, in the sense that C used it. My usage of "worse is better" means "worse is more marketable, and easier to implement", as opposed to actually being better when adopted. The original use of "worse is better" was not advocating for it as a design style in the general case, but commenting on the survival and adoption characteristics of systems designed in this style, as well as that it's often a good approach in the beginning of a project. TypeScript makes a simple promise, add types to your existing code base using an easy to understand structural type system, and it works on top of JS, just as C was designed as simple layer on top of Assembler. If C ("Worse is Better") is now being disrupted by Rust ("The Right Thing"), I think we'll see a similar player for JS / TypeScript. If you're in a position where you can decide what stack a large swath of developers are going to use, you should perhaps keep an eye open to JS / TypeScript alternatives with growing ecosystems. Your choice could turn into a competitive advantage, even if it means a smaller community in the beginning.
- vamega 6y agoThe bucklescript author now works for Facebook.
- darksaints 6y agoOh wow they went from C/C++ to JavaScript? That's just trading one dangerous footgun for another. Glad to see they finally found a better tool. I can't function in JavaScript without Typescript...I constantly have to be looking up docs cause I don't have intellisense, and once something works I'm terrified to ever touch it again. Typescript made front end development reasonable again...not perfect, but not so pathetically bad that I want to rage quit like I did before.
- sjroot 6y agoC++ is still very much used, along with Python. These languages are generally used for the overwhelming majority of our backend services. JS/TS are used in the Terminal's view layer. You can make services in these languages as well, AFAIK, but I don't think it is very common.
- Roboprog 6y agoThat seems to be pretty common statement about JavaScript, but strangely not one I share. I have been programming since the early 80s, and my experience with JS has been pretty positive, especially compared to the slog through the unreadable mud that is enterprise Java. (If I was going to rage quit on something, it would be the verbose, obtuse, repetitive Java sludge I’ve had to read the last decade and a half) Typescript solves problems I don’t have. The Jetbrains IDEs do autocomplete just fine on vanilla JS, and the documentation window automatically shows the initialization and any JSDoc for most every symbol the editor cursor touches. I avoid writing code with thousands of global symbols. OOP languages like Object Pascal and C++ are good for making lemonade from the lemon of manual memory management, but if you have efficient garbage collection, use functional programming techniques rather than OOP bloat, and many self inflicted problems go away. I hope TS doesn’t turn JS into Enterprise Java, The Next Generation. Nothing personal, most people seem to prefer that style. Just understand, there is a reason some people run away from the C++ / Java / C# / TS milieu.
- nicoburns 6y agoHave you used TS much? In my experience idiomatic TS isn't much different to idiomatic JS and a far cry from Java style OOP code (the Angular ecosystem which was admitedly an early adopter of TS is an exception and best avoided).
- coding123 6y agoI've seen some shops do things like this. Making their own tools to get around odd shitshows they've gotten themselves into. I suspect that there are a number of people within the org that aren't fans of Webpack or some other set of tools that would have made some of their decisions end up with the consequences in the article. They didn't quite state it but I suspect they're trying to use a specific stack instead of a more obvious stack to make typescript work. edit: just adding though, that this isn't surprising with a dev base of 2000 js developers.
- kristaps 6y agoThe article mentions they have around 2000 engineers, at that scale investing in custom tooling can easily become a significant net gain in productivity and stability, especially when dealing with the JS ecosystem.
- robpalmer 6y agoAgreed. The article touches on this. When you have hundreds of projects that all target the same tightly-managed evergreen runtime, there's not much justification for having each project select and maintain a different toolchain. It just leads to the same problems being solved over again, and makes it harder for developers to switch between projects. The fact that we can consider high-quality sourcemaps a solved problem (during both debugging and consolidated crash telemetry) really helps developers focus on building functionality rather than debugging a build system. I think most large companies have dedicated tooling teams for these kinds of reasons. A related viewpoint in a related thread: https://www.reddit.com/r/typescript/comments/jrgi8z/10_insights_from_adopting_typescript_at_scale/gbu75vh/ https://www.reddit.com/r/typescript/comments/jrgi8z/10_insig...
- JonathonW 6y agoI think the key here is: > Back in 2005, the company started migrating those apps from Fortran and C/C++ to server-side JavaScript Since their use of Javascript predates Node (and the rest of that ecosystem, like Webpack or Babel or whatever), they've built up their own Javascript environment that doesn't rely on Node or Node conventions at all. Not so much a "get around odd shitshows" situation as much as a parallel evolution.
- lemming 6y agoWhat is the proportion of JS libraries in the wild which provide TS type declaration files, either via DefinitelyTyped or provided by the lib itself? Is it normal to have to write your own declarations, or do most libs provide them these days?
- geewee 6y agoAlmost all of them provide them, although sometimes they are slightly out of date. I think I've had to write my own declaration files (or type a library as any) for one or two libraries in years
- a_humean 6y agoIts actually quite rare to see a library without either first or third party support these days. Many new libraries are either written in typescript, or the authors have taken care to create declaration files or contribute to definately-typed. If a library reaches any degree of popularity it usually isn't long before a third party declaration appears. Older libraries that are long abandoned by their maintainers usually don't have anything. At work we pretty much ignore all libraries that don't have types from somewhere these days, but that doesn't eliminate many things.
- horsawlarway 6y agoI agree on ignoring libraries without definitions. Having to write the definitions myself usually isn't a huge pain, but it's a big red flag showing that it's probably abandoned, and there's no community support around it anymore (or possibly ever).
- a_humean 6y agoYep, these days its basically a proxy for the kinds of smells you look out for when picking a library.
- WorldMaker 6y agoIn those cases I will sometimes try to post an offer to write their definitions (or the build step to generate definitions from slightly modified existing JSDoc comments in even more rare cases) and PR them to the project if they like. How a project responds (or doesn't) to that Issue often tells you so much about current maintenance habits.
- mirekrusin 6y ago"9. Generated declarations can inline types from dependencies" Why do they generate .d.ts files instead of publishing .ts files alongside .js files? This should solve inlining issue, no?
- robpalmer 6y agoThat's an excellent suggestion! It's true you could just have every package publish the raw TypeScript source-code. So that when an app imports a library, it type-checks against the original source code of the library. No need for DTS files from your dependencies! I have never seen this done in practice for a large system. It's not as scalable as using bare-minimum type declarations that you find in DTS files. It requires more parsing, and potentially more time to accumulate the types. Whereas DTS emit in TypeScript can flatten the resulting type into the DTS file. But if performance didn't matter, I think this would probably work. And it would eliminate the class of bugs where the generated DTS files are not 100% semantically identical to the original source code. That's another edge-case finding I omitted from the document but hope to write up another day.
- mirekrusin 6y agoIt works quite well, you can forget about src/ lib/ directories, just structure package as you want (ie files at the root), generate js files along ts in the same directory (relative paths to assets stay the same, import paths are the same in js/ts, very useful), add in vscode rule to auto hide .js file if .ts with the same name exists `{"files.exclude":{"/*.js":{"when":"$(basename).ts"}}}` - coding is pleasure, you just see and work with ts, no need to generate js files most of the time (on prepublish yes) etc.
- evmar 6y agoAnother consideration is that it only works if all the code agrees on tsconfig settings (e.g. strictness settings and path resolution). That can work in a monorepo but won't work if you mix libraries.
- mirekrusin 6y ago
- Chris_Newton 6y agoInteresting how much emphasis they seem to place on treating TS as precisely JS + types and nothing more, even to the extent of excluding evolutionary TS features. That does seem a reasonable argument for avoiding enum types in TS. Those have semantics that go beyond how enumerations work in most languages and implementing them in the underlying JS is going to introduce some runtime cost. I wonder whether their coding standards still permit const enums, though, as they are also new relative to JS but work more like traditional enumerations in C-family languages. These ought to be entirely compiled away, so it seems like the same arguments around efficiency and portability/compatibility wouldn’t apply.
- robpalmer 6y agoThere isn't much of a difference between regular enum and const enum when it comes to the usage of the enum keyword. The big difference is what they compile to - where const enum evaporates by inlining the values into the usage sites. enum is a keyword that is reserved in ECMAScript and therefore may one day clash with TypeScript. It's unlikely any ECMAScript-defined semantics for enum would match today's TypeScript enum. So it's not on any standards track. There is already a proposal for JS enum that has different semantics to TS enum, and it was created by someone on the TypeScript team: https://github.com/rbuckton/proposal-enum https://github.com/rbuckton/proposal-enum So the const form doesn't really change the hazard.
- Chris_Newton 6y agoInteresting. So even though the const form isn’t affected by the same runtime considerations, you do still prohibit it because of the potential conflict with a future use of the enum keyword by JS? I can understand the reasoning there, particularly at the scale you’re operating at. I wonder how likely it is that ECMAScript would introduce its own incompatible form of enum now that TS has become so popular. With static type checking as in TS, enums are very useful, but in the more dynamic environment of JS, the benefit is much smaller. So even if there’s nothing wrong with ECMAScript using its reserved keyword in principle, it feels like a bad idea to introduce a potential source of confusion and maybe subtle bugs when so many developers now use both languages.
- rattray 6y agoFascinating that Bloomberg started adopting server-side JS in 2005 and client-side JS only in 2012. And that they use their own deno-like JS engine.
- thom 6y agoI'd be interested to see numbers comparing the amount of server-side J(ava)Script to client-side in the decade up to 2005, because it was as common as Perl or PHP for much of the first part of my career.
- robpalmer 6y agoThe server-side JS architecture created in 2005 was presented at JSConf 2011 by Andrew Paprocki. https://www.youtube.com/watch?v=ODgs0eWAIKc https://www.youtube.com/watch?v=ODgs0eWAIKc The talk describes the system architecture and shows how the IDE is used to create applications.
- apaprocki 6y agoPlease keep in mind the date and that there are many things that are a bit dated in the video! I cringe a bit whenever this comes up — I’m sure others can relate :)
- pjmlp 6y agoServer side JavaScript exists since the language was introduced, Netscape had an application server that used it.
- jariel 6y agoIt seems what they really want is something that is not javascript. The TS team was adamant they wanted to not be a runtime, i.e. it was JS + Typing only. Partly I wish they just dumped ECMA and just made TS proper, but perhaps that's just Dart.
- robpalmer 6y agoI can empathize with this view. JavaScript is bound by backwards compatibility. It is expressed by the soundbite "don't break the web". I would love for typeof null to not be "object", and it seems appealing to say "well if JS won't fix it, maybe TS should." The problem is that this outcome has many negative effects including loss of trust. Orta (a member of the TypeScript team) describes this exact scenario in his video "How Does the TypeScript Team Try to Avoid Negative Effects on the JS Ecosystem" in which he talks about TypeScript "Embracing and Extending" JavaScript: https://www.youtube.com/watch?v=qr0TnQ2mHwY https://www.youtube.com/watch?v=qr0TnQ2mHwY The TS team seem to be firmly going in the direction of ECMAScript alignment and the JS + Types model, which is something the article advocates for too. Overall this increases my trust in the technology. On a related topic Bjarne Stroustrup once said "There are only two kinds of languages: the ones people complain about and the ones nobody uses."
- jariel 6y agoYes, the market dictated that move, a non-TS JS may have fallen flat. That said, it's MS, not some side project. They could feasibly take the road to 'pure TS' especially now that they have the core following and MS has some brand trust. There's probably a huge following of folks that would jump on a Pure TS train as long as it wasn't cloistered by all the .Net legacy. Like PureTS on Mono VM type thing.
- no_wizard 6y agoI envy this. If you guys are ever hiring, I'd do anything to be apart of such an innovative place! This is the kind of work that gets me excited to live every day. This really shows though, to the point of the article, that TypeScript at scale really lives up to its name, albeit with some quarks (and in this case, some of those quarks are also due to the environment it operates in). I have also found over the years my experience has been positive when you adopt, most notably, the points about keeping all your packages across projects/repos up to date, particularly keep your TS versions rolling upward to prevent definiftion file incompatabilities is necessary. I'm curious though, as I'm sure there are several authored libraries (not every repo I assume is a pure app), do you guys run into issues where you have to use a lot of complex typings (like using a function type to infer a given type even though the type you're inferring isn't a function, and other type dances) or has this not been the case? I've not had much of an issue with this, though I've had to do some pretty complex extends [[type]] ? stuff to get it to infer correctly in some situations where I want things to be as generic as possible. This was an informative and interesting read, and I'm grateful you guys published it. Keep up the excellent work!
- robpalmer 6y agoThanks for the feedback - I'm pleased you enjoyed it. It's true the codebase has some gnarly advanced types (generic, conditional, mapped) for expressing types for constructs created prior to TypeScript being introduced. I suspect we are pushing the limits of the compiler - quite literally TypeScript has fixed limits on recursion depth that have caused us breaks in the past. Hopefully as we refactor code with TypeScript in mind we can reduce the overall type complexity. And only because you asked... if you wish to join us, please check out https://careers.bloomberg.com https://careers.bloomberg.com
- deleted 6y ago[deleted]
- didibus 6y ago> Back in 2005, the company started migrating those apps from Fortran and C/C++ to server-side JavaScript, with client-side JavaScript arriving around 2012 Okay, I need another article about why in 2005 they chose to rewrite everything to server side JavaScript? That seems like, I don't want to say a bad decision that also led to all the issues and effort this article describes, but it kinda seems like it. In any case, it seems like an odd choice to make, especially in 2005, and especially coming from a fortran/c++ code base. So would love to hear about that and a retro on it.
- robpalmer 6y agoYes, you're right the JS@Bloomberg origin story deserves to be told in full. Probably by Andrew Paprocki. SpiderMonkey has a starring role. Until then this is as much as I can share right now: https://news.ycombinator.com/item?id=25068119 https://news.ycombinator.com/item?id=25068119 Also to be clear, we don't have a language monoculture. The app layer and hundreds of services use JS/TS. But the majority of the backend remains C++.
- didibus 6y agoThat's an interesting take. I'm now a Clojure programmer, so I totally understand the importance of a tight feedback loop. I guess in 2005 Lisp would have still been considered too "different" even though it had a longer history of backend development compared to JavaScript and an even tighter loop? I'd be very interested in an origin story. The emphasis on tight feedback loop is very novel for the time I feel, over going with Java for example, which could have been a middleground between feedback loop and type safety with much more tooling available at the time. And now with bringing types back in, slowing down the build times again, hurting the feedback loop, but it seems safety has now been favored over it, was it a change of heart, what lead to that? Anyways I'll patiently await a maybe blog post about it :) Thanks for the right up here, was very fascinating.
- addicted 6y agoI’d say you’re very wrong. Having worked there the JS ecosystem was a tremendous advantage. It’s also important to keep in mind that Bloomberg is very willing to have their best developers go ahead and build actual tooling at the compilers (and language) levels to resolve issues they may face. This occasionally leads to issues when they start diverging from the mainstream too much, but they’re also good about then stepping in and pivoting back to the mainstream development branches, which is kind of what’s happening in this article.
- woile 6y ago> undesirable features by preventing their use. I wonder if they have published those rules, I'd like to see them as I'm just diving into TS.
- tchetwin 6y agoThese rules are currently a not-readily-separable part of our build tooling. To provide earlier feedback for developers we're intending to standardise on an ESLint ruleset that will probably comprise the `no-restricted-syntax` rule: https://eslint.org/docs/rules/no-restricted-syntax https://eslint.org/docs/rules/no-restricted-syntax