Tsc-ts: TypeScript written in TypeScript

(github.com)

37 points | by tosh 4 hours ago

14 comments

  • pizlonator 2 hours ago
    I confirmed, it's faster than the Go version, which is very surprising, and super impressive!

    Caveats:

    - I don't think it's right to say that it's "written in TypeScript". In fact, it's written in the subscript of TypeScript that scriptc supports. scriptc isn't just a subset of ts; it even diverges from ts semantics in sneaky ways to facilitate its optimizations. So, these folks have really created a TypeScript-like native language with some kind of RC-GC hybrid and a bunch of caveats. Not clear if this is any better than just creating a new language.

    - Very likely that it was codeveloped with scriptc, so it's getting maximum benefit from exactly the sorts of idioms that scriptc supports well. And, I would bet they landed optimizations to scriptc specifically to get this result.

    This could be useful, assuming they invest in supporting it, and you're the sort of person who needs 2x faster ts compiles.

    • ameliaquining 2 hours ago
      Well, if you write a library in the scriptc subset, it will also work in regular JavaScript runtimes, for free. (Unless you rely on, e.g., catching runtime errors thrown by failed casts, but that's easy enough to avoid.) That seems like a clear advantage over creating a new language.

      What I do think would be nice would be if all the tweak-JS-semantics-for-optimization-purposes projects (scriptc, Static Hermes, Nova, possibly Closure Compiler) got together and agreed on a minimal set of rules that TypeScript code should follow in order to be compatible with all of them. Then there could be a push for commonly used npm packages to adhere to those rules, and advertise that they do so in order to be fully optimized.

      • pizlonator 45 minutes ago
        > Well, if you write a library in the scriptc subset, it will also work in regular JavaScript runtimes, for free.

        Not quite for free. You’d have to target the subset of both TS and scriptc and differential test, since there exist programs that work in both TS and scriptc but produce different output

  • _1tan 2 hours ago
    Did anyone benchmark against Buns‘ new time typecheck that landed in v 1.4.3? I would do it but too far away from my machine right now.
  • tallowen 2 hours ago
    The back and forth between writing tools in javascript and go or rust seems like it's in an unstable equilibrium right now:

    - Go / Rust: It's easier than ever to rewrite existing tools in more performand languages

    - Javascript: The v8 runtime for vercel or cloudflare workers is a much cheaper way to run certain workloads (e.g. conversational agents) than running a heavy weight vm. See just bash as another example project for taking advantage of this (https://github.com/vercel-labs/just-bash)

    I'm curious to see what happens!

    • cxr 1 hour ago
      That's because there's no such thing as a "performant language". A programming language is inert. It's notation. Programming languages don't get run. Binaries do.

      The only thing that can be compared are language implementations. That a given implementation, such as GCC, has an excellent code generator that emits efficient code is saying something about how great that code generator is. It's not that the input language is inherently "performant"; C programs compiled with GCC and Clang are fast. The same program compiled with My Toy C Compiler, with none of the work that has gone into LLVM and the GCC backend, is going to have different runtime characteristics.

      • jeswin 33 minutes ago
        > That's because there's no such thing as a "performant language".

        That's not true. Many languages make tradeoffs for performance. There are many things in JS (or Python) which make optimizations difficult and sometimes impossible. For example - obj[key] = "haha".

    • ameliaquining 2 hours ago
      Running Rust code in V8 via WebAssembly works today, though the tooling could benefit from a bit more polish. Go sort of works, but less well; IIUC fixing this would require adding more features to Wasm, most especially interior pointers, so that its garbage collection behavior can be made semantically compatible with Go's.
    • CharlieDigital 2 hours ago

          > ...than running a heavy weight vm.
      
      Serverless containers are a thing (GCP Cloud Run, Azure Container Apps) and seems like the right analogue.
      • ameliaquining 2 hours ago
        Those offer a more streamlined developer experience than traditional cloud VMs, but still require just as much compute resources (apart from being able to scale to zero if you can tolerate cold starts). E.g., you still have to choose how many data centers they run in and which ones, which is laden with tradeoffs, whereas every Cloudflare Worker runs in every Cloudflare DC, for free.
  • koolba 2 hours ago
    > An experimental TypeScript port of the TypeScript 7.0.2 compiler (TypeScript-Go, or tsgo), compiled to native code with scriptc.

    I don’t get it. Isn’t the golang version already native?

    Or is this one of those things where it’s not supposed to make sense?

    • anonymous908213 1 hour ago
      "Native code" doesn't mean "as fast as the code can possibly be". The native code this produces is (apparently) better optimized than the code that the Go compiler produces. It's a given that the Go compiler will produce suboptimal code, if nothing else because it includes a garbage collector in the compiled code, which introduces overhead.
      • jchw 50 minutes ago
        Go also just produces suboptimal code because it isn't maximally geared towards runtime performance. It lacks a lot of the more expensive optimization passes, like auto-vectorization.

        On the other hand, time and time again it has been proven that it can be a good language to write tools that are perfectly sufficiently fast, like esbuild. With ts-go the choice to target Go instead of Rust seems to have come down to sensibilities and ease of translation, and possibly some other factors as well. I don't think they were aiming for maximum performance, and it would be unsurprising if you could squeeze quite a bit more out of ts-go itself with some effort.

        The real benefit was getting the initial "10x" improvement, of course. Getting an additional 2x-3x is fantastic, but it's less noticeable when your codebase is already getting typechecked faster than you care to measure. For me even my largest codebases are chewed through plenty fast on ts-go, and I trust the TypeScript team to have done a good job (especially having seen some of their process for doing the port) so I think I'm good on missing out vibecoded Rust ports and whatnot. Interesting for sure, but we'll see how it all pans out in the long run.

        • anonymous908213 43 minutes ago
          Yes, I agree. I am just trying to clear up some base-level confusion about how other versions can be faster. The person who vibecoded the Rust port already said they won't maintain it. For obvious reasons! Maintaining a codebase you haven't read becomes significantly more difficult. LLM ports are easy when you have years and years of good human-written tests providing a deterministic guideline that cages them in. Even then, the fabled Bun "Rust port in 11 days", besides costing millions in tokens, introduced hundreds of bugs not caught by the tests and took over three months of human labour before being shipped as an actual release, and is still experiencing instability. And once you lose sight of the codebase, continuing to improve the software becomes a nightmare - LLMs can't write good tests, and humans can't write good tests either if they don't understand the code, so the philosophy of "write tests as the specification for LLMs to implemment" only carries you so far.
      • jerf 1 hour ago
        Is the Typescript not garbage collected somehow?

        If "scriptc" is so invasive it makes Typescript no longer even a garbage collected language then it really isn't Typescript anymore.

        • anonymous908213 1 hour ago
          My language was perhaps not as clear as it could be, given that we're talking about compiling compilers. This is about the native code of the compiler itself. The original Typescript compiler ran as regular JS inside a JS engine. The Go rewrite compiles the Typescript compiler to native code. This rewrite also compiles the Typescripter compiler to native code. In both cases, the Typescript compiler is now running directly on the OS rather than inside a JS engine, so both are significantly faster at compiling Typescript programs. However, the natively-running Typescript compiler compiled by Go still has a garbage collector itself. You don't need a garbage collector running while translating Typescript code to Javascript.
          • ameliaquining 11 minutes ago
            No, the question asked was whether binaries output by scriptc, such as the tsc-ts compiler binary, include a garbage collector that runs while they're running. (The question was not about the output of tsc-ts.) If not, then that would raise a bunch of questions about how the TypeScript code that was fed into scriptc is being executed without a GC. You are correct that a TypeScript compiler could be written in a non-GC language like Rust, but that's not the case for tsc-ts.

            The answer, according to https://scriptc.dev/docs/limitations#weak-collections-and-me..., is that scriptc relies primarily on reference counting, augmented with a cycle collector that runs at specific times, kind of like Python.

    • clarus 2 hours ago
      This version can additionally be compiled through LLVM, using a compiler from Vercel supporting a subset of TypeScript. I tried and it is 2 to 3x faster than the native Go version.
      • monster_truck 2 hours ago
        So it's just the compiling that's faster? Still not clear on the point of this, I have some pretty absurdly large typescript projects and have never felt that the compiler was slow, even before 7
    • brazukadev 1 hour ago
      both tsgo and tsc-ts are native, tsc-ts is faster and still written in TypeScript. tsc-ts was built using scriptc, a TS-to-native compiler.
  • drewbitt 3 hours ago
    I don't know whats a meme or not anymore..
    • rvz 50 minutes ago
      This entire industry has become a meme.
  • ericyd 43 minutes ago
    I would really love a "why" at the top of the readme
    • jeswin 21 minutes ago
      I'll take a shot at this even though I have no connection to vercel or scriptc. I have been working on tsonic.org for a year - which is a transpiler which will let you transpile typescript to rust, c# and mojo instead of javascript.

      First, you can't get very far without self-hosting. You'll need many extensions and hooks into the compiler, and those are probably all in TypeScript. You can't use the mainline tsc v6 compiler because it's slow and runs Javascript. scriptc will not be able to compile the v6 compiler into native code either, because that code is too dynamic. And you can't use v7 because it's written in golang.

      So the only option is to rewrite it in typescript, and compile it into native code via scriptc itself.

      We did exactly the same thing, and it's here: https://github.com/tsoniclang/tsts-legacy

      We decided to move away from it, by writing a golang-to-typescript transpiler - https://github.com/tsoniclang/gotots. That produces a working typescript version automatically from Microsoft's v7 compiler, but we just decided to not proceed with that because (a) LLMs have gotten so much better at doing these rewrites, that it's not expensive to maintain a port and (b) looking at signals from Microsoft, they don't seem to be so sure of golang anymore. I suspect it's going to get rewritten in rust.

      • girvo 5 minutes ago
        > they don't seem to be so sure of golang anymore. I suspect it's going to get rewritten in rust.

        With how “cheap” it is to achieve now, I’m pretty sure they will too. Though things like that still worry me, core tools I rely on becoming LLM-ported blobs of code that no human understands is a bit scary. I guess I’m old fashioned like that

  • einaralex 2 hours ago
    What is the purpose of this?
  • perganomoly 3 hours ago
    Seriously, the simulation needs a reboot.
    • staminade 2 hours ago
      What if we're actually running in a slop decomp of the simulation...
    • dalmo3 2 hours ago
      Or needs to be rewritten in Rust.
  • jchw 2 hours ago
    There is no obvious explanation for why you would want this anywhere I can find... Does anyone understand? If you wanted this, wouldn't it make more sense to extend the last version of TypeScript before ts-go instead? Hmm.
    • phoghed 2 hours ago
      Seems like it’s to show off scriptc unless I’m missing something else. They claim this is 2-4x faster than tsgo

      https://t.co/fMEAmv2VDY

      • ameliaquining 2 hours ago
        I guess the question is why you wouldn't use TypeScript 6 as the basis for that.
    • reactordev 2 hours ago
      Stage 1 to writing a bootstrap able language is using the intermediate step of compiling it with a compiler written in another language so that you can write a compiler for yours. I’m sure they did this in order to get a binary of the first self-compilable version.
    • 9cb14c1ec0 2 hours ago
      All the twitter types are busy rewriting typescript to speed it up, just because they can. It's becoming a meme.
  • simonbw 2 hours ago
    Now someone's gotta port this version to rust.
  • simonbw 2 hours ago
    Now someone's gotta port this to rust.
  • jdw64 2 hours ago
    Will it be faster than the Go version? But why is this even necessary? I don't get it.
    • epolanski 2 hours ago
      Apparently it's 2/3 times faster than the Go version.

      Whatever one think, the fact that there's 4 vibe coded compilers, 2 of those with 100% coverage of the official one and all being much faster than the Go version should be a wake up call for the TypeScript team.

      Despite the resources and having a huge team of people that are clearly good at programming languages and compilers, something is definitely not working as it should there if vibecoders can get much faster fully compliant compilers.

      • jerf 1 hour ago
        "Vibe coded" and "supposed a lot faster than the competition" is becoming a smell to me. LLMs have a demonstrated capability to benchmarkmaxx that is even greater than human's already substantial capabilities to do so.

        I'm not saying this isn't possible, I'm saying I'd wait a bit before I got too excited. That it seems to have held up to some other commenter's testing which was presumably not in the benchmark is an interesting sign, as a lot of time benchmarkmaxxed code falls over dead the instant you give it anything not in the benchmark. But I've still seen a whole bunch of projects "X times faster than what we told the AI to copy" that were less than met the eye to jump immediately to this must be awesome without more people trying it out seriously.

        • merb 49 minutes ago
          The vibe coded version probably work and are probably faster. But probably not more maintainable or easy to write new features for.

          But for stuff like that, it is usually not often a problem since features are most often first built as a spec and a test(suite) which by itself makes the thing easier to maintain with vibe coding. Since the implementation in itself is not import, only that it works like the spec. But that works only for software that can have a well defined specification and a test(suite). Basically it only works for things that are formally verified through the spec, which is not a lot of things at the moment.

      • jdw64 1 hour ago
        I think a bit differently. The real problem with vibe coding is that it's hard to write a precise specification of the problem. But if the specification is accurate, running the AI dozens of times tends to make it much faster than a human (purely from experience). However, for most problems where vibe coding is actually useful, a human still has to set the initial framing.
  • vc14 1 hour ago
    [flagged]
  • ouch-blurred52 1 hour ago
    [flagged]