10 interesting stories served every morning and every evening.

Chatto is now Open Source!

www.hmans.dev

Hot damn. This is the big one.

I’m happy to an­nounce that Chatto, the group and team chat ap­pli­ca­tion that I’ve been work­ing on for the past year or so, is now of­fi­cially Open Source, and avail­able for any­one to self-host.

The fastest way to give it a try is through Homebrew:

brew in­stall chat­to­corp/​tap/​chatto chatto init chatto run

See Chatto’s Getting Started Guide for de­tails. Or stick around to hear more!

Chat Just Got Real

Chatto aims to be the group chat ap­pli­ca­tion that you ac­tu­ally en­joy us­ing. You’re prob­a­bly fa­mil­iar with the one that rhymes with knack”, or the one that rhymes with beams”, or the one that rhymes with this gourd”.

Chatto is just like those. Except you’re go­ing to love how com­pact and snappy it is. And that it’s Open Source. And you can just self-host it. For free, too! (A weird thing to write, but the OSS chat app space has be­come very weird in many ways!)

This is what it looks like:

If you want to see it in ac­tion, drop by the Chatto HQ Community!

It’s de­signed to be ex­tremely easy to self-host on your own in­fra­struc­ture. In its most ba­sic shape, you just run the ex­e­cutable, and that’s it. It even serves its own fron­tend!

It’s very light on re­sources, and prob­a­bly has the snap­pi­est fron­tend that you’ve ever used in an app like this. It puts data pro­tec­tion and pri­vacy first, with all per­sonal and chat data fully en­crypted at rest with per-user keys that get shred­ded when a user de­cides to delete their ac­count.

Each Chatto server pow­ers a sin­gle com­mu­nity, with no fed­er­a­tion of data be­tween servers, nor any third-party track­ing or an­a­lyt­ics. If you want to hang out in mul­ti­ple servers at once, the client will sim­ply con­nect to all of them di­rectly. If you want to host mul­ti­ple com­mu­ni­ties, just spin up mul­ti­ple Chatto processes. Easy!

Chatto comes with full sup­port for voice and video calls, with screen-shar­ing, built in. Calls are fully end-to-end en­crypted and will scale to as many par­tic­i­pants as your in­fra­struc­ture can han­dle.

And you can use it to­day, for free, by self-host­ing it on your own server. Binaries are avail­able for Linux (x86_64 and ARM64), ma­cOS, and Windows; head over to the Chatto Self-Hosting Documentation site to get started.

Chatto Cloud

If you pre­fer some­one else to take care of the host­ing, I’m also happy to an­nounce that Chatto Cloud will soon en­ter pub­lic beta. Chatto Cloud’s of­fer­ing is very sim­ple: it pro­vides paid host­ing for Chatto servers — and that’s it. No pre­mium sub­scrip­tions, no ads, no icky bits. Just host­ing.

And it’s re­ally good host­ing! Chatto Cloud is launch­ing with fully European and European-owned in­fra­struc­ture, with more re­gions slated for launch in early 2027. Every Chatto server on Chatto Cloud ben­e­fits from au­to­matic scal­ing, nightly back­ups of all data, and zero-down­time ver­sion up­grades.

There’s no lock-in; servers hosted through Chatto Cloud are 100% com­pat­i­ble with self-hosted ones, and you can pack up your data and move into or out of Chatto Cloud at any time.

If you want to get no­ti­fied about the start of the beta, please see the end of this post for a low-vol­ume newslet­ter you can sub­scribe to.

What’s Next for Chatto

Chatto is now at ver­sion 0.4. I con­sider it sta­ble enough for pro­duc­tion use, but there are a few im­por­tant fea­tures still miss­ing — head over to the Chatto Roadmap if you want an overview.

The fo­cus for Chatto 0.5 will be on ad­di­tional safety fea­tures (content re­port­ing and mod­er­a­tion) as well as pol­ish­ing the client, par­tic­u­larly its multi-server func­tion­al­ity. I have some fun stuff planned for this that I can’t wait to put into peo­ple’s hands.

I ex­pect Chatto to hit 1.0.0 in about 6 – 12 months. Until then, there may still be break­ing changes, even though I’ll be try­ing to keep them to a min­i­mum. If you do de­cide to self-host, please be ready to up­date to new ver­sions as they are re­leased.

Get in Touch

It’s been an ex­cit­ing jour­ney so far and I’m look­ing for­ward to find­ing out what’s ahead. If you’re self-host­ing Chatto, I’m su­per ea­ger to hear from you about your ex­pe­ri­ence — please don’t hes­i­tate to head over to the Chatto HQ com­mu­nity and get in touch.

Also please feel free to drop by and say hello if you’re in­ter­ested in Chatto for your com­pany, Open Source pro­ject, or sim­i­lar. I’d love to learn more about your re­quire­ments, and help you get set up.

Links

Chatto HQ Community - we have a #self-hosting sup­port chan­nel!

Chatto Self-Hosting Documentation

GitHub Repository

Chatto on Bluesky

Newsletter

If you want to be no­ti­fied about new re­leases or the start of Chatto Cloud’s beta, you’re in­vited to sub­scribe to the Chatto an­nounce­ments newslet­ter. It’s su­per low-vol­ume (~1 email per month), and is only used for no­ti­fy­ing you when ex­cit­ing new stuff be­comes avail­able.

FTC secures right to repair settlement with farming equipment giant John Deere | AP News

apnews.com

It looks like John Deere own­ers can soon feel free to fix their own ma­chines.

The Federal Trade Commission and at­tor­neys gen­eral from sev­eral states se­cured a right-to-re­pair set­tle­ment Wednesday with agri­cul­ture equip­ment gi­ant Deere & Co. — com­monly known as John Deere — that re­quires the com­pany to let farm­ers and in­de­pen­dent shops fix their own equip­ment.

The Illinois-based man­u­fac­turer has faced com­plaints for years for with­hold­ing the soft­ware needed for re­pairs and forc­ing cus­tomers to use au­tho­rized deal­ers in­stead of in­de­pen­dent ones.

This marks the sec­ond right-to-re­pair set­tle­ment Deere has reached this year, fol­low­ing a sep­a­rate $99 mil­lion class-ac­tion set­tle­ment with farm­ers in April. Though the class-ac­tion com­pen­sated con­sumers, the FTCs set­tle­ment in­stead re­quires Deere to make its re­pair ser­vices avail­able to equip­ment own­ers and in­de­pen­dent shops.

The FTC and at­tor­neys gen­eral from Arizona, Illinois, Michigan, Minnesota and Wisconsin brought the an­titrust law­suit in January 2025, ar­gu­ing that Deere had il­le­gally re­stricted farm­ers and in­de­pen­dent shops that might oth­er­wise ser­vice them from re­pair­ing farm equip­ment such as trac­tors. Deere also makes en­gines and equip­ment for forestry, land­scap­ing and con­struc­tion.

Under the or­der filed in Illinois, Deere will now be re­quired to make di­ag­nos­tic and re­pair tools avail­able to equip­ment own­ers and in­de­pen­dent re­pair shops, not only its own net­work of au­tho­rized deal­ers. It also pre­vents Deere deal­ers from re­tal­i­at­ing against equip­ment own­ers or re­pair shops who choose to fix their own equip­ment in­stead of pay­ing for Deere’s ser­vices. The or­der is headed to Judge Iain D. Johnston for his ap­proval.

For too long, Arizona farm­ers and in­de­pen­dent me­chan­ics have been at the mercy of Deere’s mo­nop­oly over re­pair tools, forced to wait — and pay — for au­tho­rized deal­ers just to fix bro­ken trac­tors and other equip­ment,” Arizona Attorney General Kris Mayes said in a state­ment Wednesday.

Deere must pay $1 mil­lion col­lec­tively to the five states for an­titrust en­force­ment costs and will be sub­ject to strict com­pli­ance over­sight for the next 10 years.

In the com­plaint, the FTC ar­gued that Deere pro­vides a ser­vice soft­ware tool to au­tho­rized deal­ers but does not pro­vide the full ver­sion to equip­ment own­ers or in­de­pen­dent shops. Deere had said the law­suit was base­less, de­nied that its dis­tri­b­u­tion of ser­vice tools was an­ti­com­pet­i­tive and ar­gued that it could not mo­nop­o­lize ser­vices since it does not di­rectly pro­vide them.

Sign up for Morning Wire: Our flag­ship newslet­ter breaks down the biggest head­lines of the day.

Deere main­tained its com­mit­ment to in­de­pen­dent re­pair in a state­ment Wednesday, adding that the agree­ment with the FTC re­in­forces its in­no­va­tion of more flex­i­ble re­pair op­tions.

This is good news for our cus­tomers and for the fu­ture of how Deere equip­ment is sup­ported,” said Denver Caldwell, vice pres­i­dent of af­ter­mar­ket and cus­tomer sup­port.

Right-to-repair has be­come an in­creas­ingly com­mon is­sue over the years, es­pe­cially for tech prod­ucts, with con­sumers com­plain­ing that even sim­ple re­pairs can only be done by com­pany-au­tho­rized deal­ers.

openai.com

Attention Required! | Cloudflare

x.ai

Why have I been blocked?

This web­site is us­ing a se­cu­rity ser­vice to pro­tect it­self from on­line at­tacks. The ac­tion you just per­formed trig­gered the se­cu­rity so­lu­tion. There are sev­eral ac­tions that could trig­ger this block in­clud­ing sub­mit­ting a cer­tain word or phrase, a SQL com­mand or mal­formed data.

What can I do to re­solve this?

You can email the site owner to let them know you were blocked. Please in­clude what you were do­ing when this page came up and the Cloudflare Ray ID found at the bot­tom of this page.

Announcing TypeScript 7.0

devblogs.microsoft.com

Today we are proud to an­nounce the avail­abil­ity of TypeScript 7, a 10x faster na­tive port of TypeScript!

Since its early days, TypeScript has promised to de­liver on JavaScript that scales. By bring­ing strong type-check­ing and rich tool­ing to the world of JavaScript, TypeScript made it pos­si­ble to build non-triv­ial high-qual­ity apps across plat­forms.

Last year, our team un­veiled TypeScript’s next step in scal­ing: mak­ing every part of the toolset an or­der of mag­ni­tude faster. The mis­sion was a na­tive port of TypeScript built in Go that could make the most of mod­ern hard­ware. This port was done as faith­fully as pos­si­ble, writ­ing new code while main­tain­ing the struc­ture and logic of the orig­i­nal code­base to keep re­sults con­sis­tent and com­pat­i­ble be­tween the two com­pil­ers. The key dif­fer­ence is that with this new code­base, TypeScript 7 brings na­tive code speed, shared mem­ory mul­ti­thread­ing, and a num­ber of new op­ti­miza­tions that typ­i­cally yield speedups be­tween 8x and 12x on full builds.

Just as with any other re­lease, TypeScript 7 is avail­able via npm:

npm in­stall -D type­script

That will get you the new tsc ex­e­cutable in your work­space (which you can run via npx tsc). Of course, a big part of the TypeScript ex­pe­ri­ence is also about ed­i­tor sup­port. Your fa­vorite code ed­i­tor should eas­ily sup­port TypeScript 7 with its new sup­port for the lan­guage server pro­to­col (LSP), and its new speed and mul­ti­thread­ing im­prove­ments. Whether you’re us­ing some­thing like VS Code, Visual Studio, WebStorm, or any other mod­ern ed­i­tor, TypeScript 7 should work great. Just check your ed­i­tor’s doc­u­men­ta­tion — for ex­am­ple, VS Code has a ded­i­cated ex­ten­sion for TypeScript 7 that you can use to­day, and Visual Studio will au­to­mat­i­cally en­able TypeScript 7 based on your work­space.

What Does A Faster TypeScript Mean?

A faster TypeScript sounds great on pa­per, but what does it mean in prac­tice? Maybe it helps to think about where TypeScript comes up at every stage of de­vel­op­ment.

A typ­i­cal day of de­vel­op­ment might in­volve open­ing your ed­i­tor, open­ing a TypeScript file, and run­ning an op­er­a­tion like find-all-ref­er­ences across your pro­jects. Then as you’d start to make ed­its, maybe you’d ex­pect auto-com­ple­tions to pop up, and get red squig­gles on the fly as you’d make ed­its. When you (and more re­cently, per­haps an AI agent) were ready to build your pro­ject, you’d run tsc, check the out­put for er­rors, and then run your gen­er­ated code some­how.

A faster TypeScript means every part above is stream­lined. Waiting for your ed­i­tor to fully load your pro­ject will feel in­stan­ta­neous. Delays on find-all-ref­er­ences, auto-com­ple­tion, and di­ag­nos­tics should take a frac­tion of the time they used to. And when you run tsc, maybe in –watch mode, you’ll be able to tighten your feed­back loop and it­er­ate faster than ever be­fore.

You can see this on real-world pro­jects. In fact, you can try com­par­ing on a few open-source pro­jects your­self. Here are the build times of run­ning TypeScript 6 and 7 on some fairly large open source code­bases.

TypeScript 7 also typ­i­cally does bet­ter while ask­ing for less ag­gre­gate mem­ory over the span of a build.

Of course, there’s more to the ex­pe­ri­ence than the full build. On the same com­puter, open­ing a file with an er­ror in the VS Code code­base would pre­vi­ously take about 17.5 sec­onds from the time you opened the ed­i­tor to the time you saw the first er­ror. With TypeScript 7, it’s un­der 1.3 sec­onds — over 13x faster.

Battle-Tested and Ready for Production

The TypeScript pro­ject con­tains tens of thou­sands of tests built over more than a decade that run on every com­mit on our main branch. They’ve en­sured every one of our re­leases is sta­ble and re­li­able.

But TypeScript 7 is no or­di­nary re­lease. Beyond our test suite, we’ve lever­aged a num­ber of dif­fer­ent re­sources to make sure TypeScript 7 is solid for pro­duc­tion use.

Over the last year we’ve worked with many large teams in­ter­nally and ex­ter­nally to test TypeScript 7 on real-world code­bases. The re­sults have been over­whelm­ingly pos­i­tive, with en­tire com­pa­nies re­port­ing that TypeScript 7 has been sta­ble, fast, and easy to adopt. For ex­am­ple, the VS Code team re­cently high­lighted their ex­pe­ri­ence with TypeScript 7’s pre­view re­leases to move faster in their de­vel­op­ment cy­cle. We’ve also worked with Microsoft teams like Loop, Office, PowerBI, Teams, and Xbox to en­sure that TypeScript is ready for the largest of code­bases. Likewise, com­pa­nies like Bloomberg, Canva, Figma, Google, Lattice, Linear, Miro, Notion, Sentry, Slack, Vanta, Vercel, VoidZero, and more have worked with us to test TypeScript 7 on their code­bases and given us feed­back to make it bet­ter.

Additionally, we’ve re­built much of our broader test in­fra­struc­ture to run on TypeScript 7. TypeScript 6 and ear­lier had au­to­mated and on-de­mand test­ing for TypeScript and JavaScript pro­jects on GitHub to de­tect re­gres­sions in the com­piler and lan­guage ser­vice. The same test­ing is back, and run­ning against TypeScript 7, find­ing is­sues in real code­bases so we can find gaps in our core test suite and ship a bet­ter ex­pe­ri­ence.

The com­bi­na­tion of ex­plicit feed­back, au­to­mated crash re­ports, and ag­gres­sive test­ing has made a mea­sur­able dif­fer­ence in qual­ity. In fact, our data in­sights have shown us that TypeScript 7.0’s new lan­guage server has ac­tu­ally re­duced fail­ing lan­guage server com­mands by over 80%, and re­duced server crashes by over 60% com­pared to that of TypeScript 6.0.

We’ve also heard some in­cred­i­ble feed­back from teams at scale:

Slack en­gi­neers have told us that TypeScript 7 elim­i­nated 40% of their merge queue time and brought type-check­ing time in CI from about 7.5 min­utes to 1.25 min­utes. Local de­vel­op­ment in the ed­i­tor was pre­vi­ously al­most unusable” due to lan­guage server load times and en­gi­neers would typ­i­cally let CI do a full type-check. TypeScript 7 has been able to load the same code­base in a few sec­onds and made lo­cal type-check­ing fea­si­ble again.

Builds at Vanta have dra­mat­i­cally im­proved, show­ing a speedup of up to 9x faster on one of their biggest pro­jects.

Similarly, the News Services team at Microsoft told us that adopt­ing TypeScript 7 saved them 400 hours a month wait­ing for CI builds.

Last year, en­gi­neers work­ing on PowerBI de­scribed TypeScript 7 in the ed­i­tor as life-saving” for work­ing on their code­base. They adopted the ex­pe­ri­ence as a de­fault even be­fore TypeScript 7 sup­ported re­name func­tion­al­ity in VS Code.

Developers work­ing on Loop’s monorepo were also ec­sta­tic. The pre­vi­ous ed­i­tor ex­pe­ri­ence was de­scribed as un­us­able at their scale, whereas the TypeScript 7 ex­pe­ri­ence has been amazing” to use.

Canva de­vel­op­ers have told us that TypeScript 7’s lan­guage ser­vice shows dra­matic speedups, go­ing from about 58 sec­onds to see­ing the first er­ror in their ed­i­tors to about 4.8 sec­onds.

Running Side-by-Side with TypeScript 6.0

While TypeScript 7.0 is here, it does not ship with an API. We ex­pect TypeScript 7.1 to ship with a new (and dif­fer­ent) API, but un­til then we have made it a pri­or­ity to en­sure TypeScript can be run side-by-side with TypeScript 6.0 for util­i­ties that still need some pro­gram­matic ac­cess to the com­piler (such as type­script-es­lint).

As part of the 6.0/7.0 tran­si­tion process, we’ve pub­lished a new com­pat­i­bil­ity pack­age, @typescript/typescript6. This pack­age pro­vides an ex­e­cutable named tsc6, so that if needed, you can in­stall TypeScript 7.0 (which ships its own tsc bi­nary) side-by-side with­out nam­ing con­flicts. The new pack­age also re-ex­ports the TypeScript 6.0 API, so that you can use tsc for TypeScript 7, while other tool­ing can con­tinue to rely on 6.0.

Because some tools like type­script-es­lint ex­pect to im­port from type­script di­rectly via peer de­pen­den­cies, we rec­om­mend achiev­ing this via npm aliases. You should be able to run the fol­low­ing com­mand

npm in­stall -D type­script@npm:@type­script/​type­script6

or mod­ify your pack­age.json as fol­lows:

{ devDependencies”: { typescript”: npm:@typescript/typescript6@^6.0.2”, } }

Note that do­ing this will leave you only with a tsc6 ex­e­cutable. To get 7.0’s tsc, you can add an­other alias for TypeScript 7 and npx tsc will just work with 7.0:

{ devDependencies”: { @typescript/native”: npm:typescript@^7.0.2”, typescript”: npm:@typescript/typescript6@^6.0.2” } }

Nightly Builds and @typescript/native-preview

Until now, most de­vel­op­ers have in­stalled TypeScript 7 via the @typescript/native-preview pack­age. This pack­age shipped nightly builds of the new code­base, and has served the com­mu­nity well with over 8.5 mil­lion weekly down­loads!

However, go­ing for­ward, nightly builds will soon re­sume un­der the stan­dard type­script pack­age with the next tag. You can in­stall it with:

npm in­stall -D type­script@next

Custom Scaling: Parallelization and Controls

TypeScript 7.0 now per­forms many steps in par­al­lel, in­clud­ing pars­ing, type-check­ing, and emit­ting. Some of these steps, like pars­ing and emit­ting can mostly be done in­de­pen­dently across files. As such, par­al­leliza­tion au­to­mat­i­cally scales well with larger code­bases with rel­a­tively lit­tle over­head. But not every step in a TypeScript build is eas­ily par­al­leliz­able.

TypeScript 7 in­tro­duces the ex­per­i­men­tal –checkers and –builders flags to fine-tune the par­al­leliza­tion be­hav­ior for less-triv­ial steps like type-check­ing and pro­ject ref­er­ence build­ing. It also in­tro­duces a –singleThreaded flag to dis­able par­al­leliza­tion en­tirely, which can be use­ful for de­bug­ging or run­ning in en­vi­ron­ments with lim­ited re­sources.

Type-Checker Parallelization

Other steps, like type-check­ing, have more com­plex de­pen­den­cies across files. Most files end up re­ly­ing on the same type in­for­ma­tion from their de­pen­den­cies and the global scope, and so run­ning type-check­ers com­pletely in­de­pen­dently would be waste­ful — both in com­pu­ta­tion and mem­ory. On the other hand, type-check­ing oc­ca­sion­ally re­lies on the rel­a­tive or­der­ing of in­for­ma­tion in a pro­gram, and so type-check­ing from scratch must al­ways check the same files in an iden­ti­cal or­der to en­sure the same re­sults.

To en­able par­al­leliza­tion while avoid­ing these pit­falls, TypeScript 7.0 cre­ates a fixed num­ber of type-checker work­ers with their own view of the world. These type-check­ing work­ers may end up du­pli­cat­ing some com­mon work, but given the same in­put files, they will al­ways di­vide them iden­ti­cally and pro­duce the same re­sults.

The de­fault num­ber of type-check­ing work­ers is 4, but it can be con­fig­ured with the new –checkers flag. You may find that in­creas­ing this num­ber can fur­ther speed up builds on larger code­bases where typ­i­cal ma­chines have more CPU cores, but will typ­i­cally come at the cost of in­creased mem­ory us­age. For ex­am­ple, in the table above, we ran TypeScript 7 with its de­fault of –checkers 4. Here’s what the re­sults look like on the same ma­chine with –checkers 8.

As you can see, these code­bases get a bet­ter speedup from ded­i­cat­ing more cores, but re­sults will dif­fer across pro­jects and un­der­ly­ing ma­chines.

On the other hand, on ma­chines with fewer CPU cores and less mem­ory (e.g. CI run­ners) you may want to de­crease this num­ber to avoid un­nec­es­sary or in­ci­den­tal over­head. You can spec­ify a value as low as –checkers 1, ef­fec­tively mak­ing type-check­ing sin­gle-threaded and elim­i­nat­ing du­pli­cate work.

In rare cases, vary­ing the num­ber of –checkers may sur­face or­der-de­pen­dent re­sults. Specifying a fixed num­ber of check­ers across build en­vi­ron­ments can help en­sure every­one is get­ting the same re­sults, but is up to the dis­cre­tion of your team.

Project Reference Builder Parallelization

TypeScript 7.0 can par­al­lelize builds within a pro­ject, but it can now also build mul­ti­ple pro­jects at once as well. This be­hav­ior can be con­fig­ured with the new –builders flag, which con­trols the num­ber of par­al­lel pro­ject ref­er­ence builders that can run at once when run­ning un­der –build. This can be par­tic­u­larly help­ful for monore­pos with many pro­jects.

Like –checkers, in­creas­ing the num­ber of builders can speed up builds, but may come at the cost of in­creased mem­ory us­age. It also has a mul­ti­plica­tive ef­fect with –checkers, so it’s im­por­tant to find the right bal­ance for your ma­chine and code­base. For ex­am­ple, build­ing with –checkers 4 –builders 4 al­lows up to 16 type-check­ers to run at once, which may be ex­ces­sive.

Unlike –checkers, vary­ing the num­ber of builders should not pro­duce dif­fer­ent re­sults; how­ever, build­ing pro­ject ref­er­ences is fun­da­men­tally bot­tle­necked by the de­pen­dency graph of pro­jects (with the ex­cep­tion of type-check­ing on code­bases that lever­age –isolatedDeclarations and sep­a­rate syn­tac­tic de­c­la­ra­tion file emit).

Single-Threaded Mode

In some cases, it can be help­ful to en­force sin­gle-threaded op­er­a­tion through­out the com­piler. This may be use­ful for de­bug­ging, com­par­ing per­for­mance with TypeScript 6 and 7, when or­ches­trat­ing par­al­lel builds ex­ter­nally, or for run­ning in en­vi­ron­ments with very lim­ited re­sources. To en­able sin­gle-threaded mode, you can use the new –singleThreaded flag. This will not only cap the num­ber of type-check­ing work­ers to 1, but also en­sure pars­ing and emit­ting are done in a sin­gle thread.

Improved –watch Mode

TypeScript 7 ships with a com­pletely re­built –watch mode. –watch is now pow­ered by a new foun­da­tion based on the Parcel bundler’s file-watcher that pro­vides ef­fi­cient and sta­ble cross-plat­form file watch­ing ca­pa­bil­i­ties.

When our team set out to port our file watch­ing logic, we en­coun­tered a few chal­lenges with cross-plat­form file watch­ing in Go. The stan­dard li­brary does­n’t pro­vide a built-in file watch­ing API, and ex­ist­ing third-party li­braries we ex­plored had var­i­ous is­sues with sta­bil­ity, per­for­mance, cross-plat­form sup­port, or is­sues with build tool­ing in­te­gra­tion. We were able to build so­lu­tions around polling pe­ri­od­i­cally to check for file changes, and this worked broadly across op­er­at­ing sys­tems; how­ever it was com­pu­ta­tion­ally ex­pen­sive, es­pe­cially at larger-scale pro­jects with many de­pen­den­cies in node_­mod­ules. Even with dy­namic sched­ul­ing strate­gies, we found that pure-polling so­lu­tions were too tax­ing for gen­eral use.

For many years, Visual Studio Code has re­lied on @parcel/watcher, and in re­cent years TypeScript in VS Code has re­lied on its file watch­ing ca­pa­bil­i­ties in­di­rectly. While it seemed promis­ing, one of the prob­lems for us with Parcel’s watcher is that it’s writ­ten in C++, and in turn re­quires a full C++ tool­chain to build. Given our pos­i­tive ex­pe­ri­ence with Parcel’s watcher in VS Code, we ex­plored port­ing it to Go with a few min­i­mal as­sem­bly shims to avoid in­tro­duc­ing a new tool­chain de­pen­dency.

The ex­plo­ration has been a suc­cess — what started as a very di­rect trans­la­tion from C++ to Go was fur­ther re­fined into id­iomatic Go that still passes the ported test suite. The watcher is a self-con­tained pack­age that has al­lowed us to keep a clean sep­a­ra­tion of con­cerns be­tween what we care to watch and why. We are now see­ing sig­nif­i­cant re­source im­prove­ments in –watch mode across plat­forms, and have been hear­ing pos­i­tive feed­back from ear­lier users of TypeScript 7.

We’d like to ex­tend our thanks to Devon Govett whose work on Parcel has pro­vided im­mense ben­e­fits to both the Visual Studio Code and TypeScript pro­jects. We hope this port will pro­vide op­por­tu­ni­ties and in­sights for the orig­i­nal Parcel watcher code­base over time.

Updates Since 5.x, and New Behaviors from 6.0

TypeScript 7.0 is made to be com­pat­i­ble with TypeScript 6.0’s type-check­ing and com­mand-line be­hav­ior. Practically any TypeScript code that com­piles cleanly with TypeScript 6.0 (with the sta­ble­Type­Order­ing flag on, and with­out any ig­nore­Dep­re­ca­tions flag set) should com­pile iden­ti­cally in TypeScript 7.0.

With that said, TypeScript 7.0 adopts 6.0’s new de­faults, and pro­vides hard er­rors in the face of any flags and con­structs dep­re­cated in TypeScript 6.0. This is no­table as 6.0 is still rel­a­tively new, and many pro­jects will need to adapt to its new be­hav­iors. We en­cour­age de­vel­op­ers to adopt TypeScript 6.0 to make the tran­si­tion to TypeScript 7.0 eas­ier, and you can also read the TypeScript 6.0 re­lease blog post for more de­tails on these dep­re­ca­tions.

At a glance, the no­table de­fault changes to con­fig­u­ra­tion are:

strict is true by de­fault.

mod­ule de­faults to es­next.

tar­get de­faults to the cur­rent sta­ble ECMAScript ver­sion im­me­di­ately pre­ced­ing es­next.

noUnchecked­Side­Ef­fectIm­ports is true by de­fault.

li­bRe­place­ment is false by de­fault.

sta­ble­Type­Order­ing is true by de­fault, and can­not be turned off.

root­Dir now de­faults to ./, and in­ner source di­rec­to­ries must be ex­plic­itly set.

types now de­faults to [], and the old be­hav­ior can be re­stored by set­ting it to [“*”].

We be­lieve the root­Dir and types changes may be the most surprising” changes, but they can be mit­i­gated eas­ily. Projects where the tscon­fig.json sits out­side of a di­rec­tory like src will sim­ply need to in­clude root­Dir to pre­serve the same di­rec­tory struc­ture.

{ compilerOptions”: { // … + rootDir”: ./src” }, include”: [”./src”] }

For the types change, pro­jects that de­pend on spe­cific global de­c­la­ra­tions will need to list them ex­plic­itly. For ex­am­ple,

{ compilerOptions”: { // Explicitly list the @types pack­ages you need (e.g. bun, mocha, jas­mine, etc.) + types”: [“node”, jest”] } }

The dep­re­ca­tions that have turned into hard er­rors with no-op be­hav­ior are:

tar­get: es5 is no longer sup­ported.

down­levelIt­er­a­tion is no longer sup­ported.

mod­uleRes­o­lu­tion: node/​node10 are no longer sup­ported, with nodenext and bundler be­ing rec­om­mended in­stead.

mod­ule: amd, umd, sys­temjs, none are no longer sup­ported, with es­next or pre­serve be­ing rec­om­mended in con­junc­tion with bundlers or browser-based mod­ule res­o­lu­tion.

baseUrl is no longer sup­ported, and paths can be up­dated to be rel­a­tive to the pro­ject root in­stead of baseUrl.

mod­uleRes­o­lu­tion: clas­sic is no longer sup­ported, and bundler or nodenext are the rec­om­mended re­place­ments.

es­Mod­uleIn­terop and al­lowSyn­thet­icDe­fault­Im­ports can­not be set to false.

al­waysStrict is as­sumed to be true and can no longer be set to false.

The mod­ule key­word can­not be used in name­space de­c­la­ra­tions.

The as­serts key­word can­not be used on im­ports, and must use the with key­word in­stead (to align with de­vel­op­ments on ECMAScript’s im­port at­tribute syn­tax).

/// <reference no-de­fault-lib /> di­rec­tives are no longer re­spected un­der skipDe­fault­LibCheck.

Command line builds can­not take file paths when the cur­rent di­rec­tory con­tains a tscon­fig.json file un­less passed an ex­plicit –ignoreConfig flag.

Template Literal Types Now Preserve Unicode Code Points

TypeScript 7.0 now treats Unicode code points more nat­u­rally when in­fer­ring from tem­plate lit­eral types. For ex­am­ple:

type HeadTail<S> = S ex­tends `${infer Head}${infer Tail}` ? [Head, Tail] : never;

type Result = HeadTail<“😀abc”>; // ^ // In 7.0: [“😀, abc”] // Previously: [“\ud83d”, \ude00abc”]

Previously, TypeScript fol­lowed JavaScript’s UTF-16 in­dex­ing be­hav­ior here and split 😀 into two halves of a sur­ro­gate pair (\ud83d and \ude00). That was tech­ni­cally con­sis­tent with in­dex­ing in JavaScript (e.g. the in­ferred Head type was equal to 😀abc”[0]), but it usu­ally was­n’t what peo­ple in­tended, and could pro­duce string lit­eral types con­tain­ing un­paired sur­ro­gates that aren’t se­man­ti­cally mean­ing­ful.

This is a break­ing change for type-level string ma­nip­u­la­tion that in­ten­tion­ally mod­eled UTF-16 code units, such as some string Length util­i­ties. In prac­tice, we ex­pect the new be­hav­ior to be more use­ful and less sur­pris­ing: tem­plate lit­eral in­fer­ence now fol­lows the same in­tu­ition as it­er­at­ing a string with for…of or spread­ing it with […str], where 😀 is treated as one unit.

JavaScript Differences

As we ported the ex­ist­ing code­base, we also took the op­por­tu­nity to re­visit how our JavaScript sup­port works.

TypeScript orig­i­nally sup­ported JavaScript files by us­ing JSDoc com­ments and rec­og­niz­ing cer­tain code pat­terns for analy­sis and type in­fer­ence. Lots of the time, this was based on pop­u­lar cod­ing pat­terns, but oc­ca­sion­ally it was based on what­ever peo­ple might be writ­ing that Closure and the JSDoc doc gen­er­at­ing tool might un­der­stand. While this ap­proach was help­ful for de­vel­op­ers with loosely-writ­ten JSDoc code­bases, it re­quired a num­ber of com­pro­mises and spe­cial cases to work well, and di­verged in a num­ber of ways from TypeScript’s analy­sis in .ts files.

In TypeScript 7.0, we have re­worked our JavaScript sup­port to be more con­sis­tent with how we an­a­lyze TypeScript files. Some of the dif­fer­ences in­clude:

Rewriting Bun in Rust

bun.com

Disclosure: Bun was ac­quired by Anthropic in December 2025. I and oth­ers on the Bun team work at Anthropic. I used a pre-re­lease ver­sion of Claude Fable 5 for much of the Rust rewrite.

Bun started as a line-for-line port of es­build’s JavaScript & TypeScript tran­spiler from Go to Zig. I wrote my first line of Zig on April 16, 2021. I bet on Zig af­ter see­ing the sin­gle-page Zig Language Reference on Hacker News and get­ting re­ally ex­cited about the low-level con­trol and care for per­for­mance.

From the start, Bun’s scope was mas­sive:

JavaScript, TypeScript, and CSS tran­spiler, mini­fier, and bundler

npm-com­pat­i­ble pack­age man­ager

Jest-like test run­ner

Node.js & TypeScript-compatible mod­ule res­o­lu­tion

HTTP/1.1 & WebSocket client

Node.js API im­ple­men­ta­tions like fs, net, tls, and dozens of other mod­ules

The ini­tial ver­sion of Bun was writ­ten by me in 1 year, in a cramped Oakland apart­ment, pre-LLM, in Zig. The de­fault out­come for am­bi­tiously-scoped pro­jects like Bun is join­ing the grave­yard of dead side pro­jects on a GitHub pro­file page. Zig made Bun pos­si­ble. I would never have been able to build this much in 1 year if it was­n’t for Zig.

Nowadays, Bun’s CLI gets over 22 mil­lion monthly down­loads. Popular tools like Claude Code and OpenCode bet on Bun as their run­time. Vercel, Railway, DigitalOcean and more have 1st-party sup­port for Bun.

Bun’s scope has also been a chal­lenge for sta­bil­ity. Here’s a small sam­ple of bugs we fixed in Bun v1.3.14:

heap-use-af­ter-free crash in node:zlib when call­ing .reset() on a zlib, Brotli, or Zstd stream while an async .write() is still in progress on the thread­pool

use-af­ter-free crash in node:zlib when an on­error call­back is­sued a re-en­trant write() fol­lowed by close() on na­tive han­dles

use-af­ter-free crashes in node:http2 when re-en­trant JS call­backs (e.g. ses­sion.re­quest() in­side a time­out lis­tener, an op­tions get­ter, or a write call­back) trig­gered a hashmap re­hash, in­val­i­dat­ing in­ter­nal stream point­ers

use-af­ter-free in UDPSocket.send() and send­Many() where user code in val­ueOf() or toString() call­backs could de­tach an ArrayBuffer be­tween pay­load cap­ture and the ac­tual send

crash and out-of-bounds read in Buffer#copy and Buffer#fill when a val­ueOf call­back de­taches or re­sizes the un­der­ly­ing ArrayBuffer dur­ing ar­gu­ment co­er­cion

heap out-of-bounds write in UDPSocket.sendMany() when the sock­et’s con­nec­tion state changed mid-it­er­a­tion via user JS call­backs

mem­ory leak in crypto.scrypt where the call­back and pro­tected pass­word/​salt buffers were never re­leased when the out­put buffer al­lo­ca­tion failed

SSLWrapper.init leaked the strdup’d passphrase on er­ror paths

mem­ory leak in tlsSocket.set­Ses­sion() where each call leaked one SSL_SESSION (~6.5 KB per call) due to a miss­ing SSL_SESSION_free af­ter d2i_SS­L_SES­SION

mem­ory leak where fs.watch() watch­ers were never garbage col­lected af­ter .close(), caused by a ref­er­ence count un­der­flow that per­ma­nently pinned each watcher as a GC root

dou­ble-free crash in the CSS parser when back­ground-clip had ven­dor pre­fixes and multi-layer back­grounds

DuplexUpgradeContext was never freed — a full leak per tls.con­nect({ socket: du­plex })

race con­di­tion crash in MessageEvent where the GC marker thread could ob­serve a torn vari­ant in m_­data dur­ing con­cur­rent ac­cess from a BroadcastChannel or MessagePort

We could have kept fix­ing these kinds of bugs one-off in per­pe­tu­ity, but we owe it to our users count­ing on us to do bet­ter than that, and sys­tem­at­i­cally pre­vent these kinds of bugs from re­cur­ring.

What we were al­ready do­ing

We patched the Zig com­piler to add Address Sanitizer sup­port. We run our test suite with ASAN on every com­mit.

We ship Zig safety-checked ReleaseSafe builds on Windows

We fuzz Bun’s run­time APIs 24/7 us­ing Fuzzilli, the JavaScript en­gine fuzzer used by V8 & JavaScriptCore

We have a whole lot of end-to-end mem­ory leak tests

This is more than many pro­jects do.

Just be re­ally smart and don’t make mis­takes?

Our bug­fix list felt bad and I was tired of go­ing to sleep wor­ry­ing about crashes in Bun. I don’t blame Zig for that - other users of Zig don’t have the bugs we had, and mix­ing GC with man­u­ally-man­aged mem­ory is an un­com­mon enough thing for soft­ware to need that no lan­guage re­ally de­signs for it. We would­n’t have got­ten this far if not for Zig, and I’ll al­ways be grate­ful. Until very re­cently, pro­gram­ming lan­guage choice was a one-way de­ci­sion for a pro­ject like Bun.

JavaScript is a garbage-col­lected lan­guage and mod­ern JavaScript en­gines like JavaScriptCore (and V8) have strict rules around ex­cep­tion han­dling and the garbage col­lec­tor. Zig, like C, does­n’t man­age mem­ory for you and this is a trade­off that for many pro­jects is a great rea­son to use Zig. Zig does not have con­struc­tors/​de­struc­tors, and most cleanup is ex­pected to be writ­ten out ex­plic­itly at each call site with de­fer.

For Bun, cor­rectly han­dling the life­times of garbage-col­lected val­ues and man­u­ally-man­aged val­ues has been a ma­jor source of sta­bil­ity is­sues - most of­ten small mem­ory leaks and oc­ca­sion­ally, crashes. Every mem­ory al­lo­ca­tion has to be metic­u­lously re­viewed. Where do these bytes get freed? How do we en­sure it only gets freed once? Did we check for JavaScript ex­cep­tions prop­erly? Is this garbage-col­lected pointer vis­i­ble to the con­ser­v­a­tive stack scan­ner? Is this garbage col­lected mem­ory or man­u­ally man­aged mem­ory?

For sta­bil­ity is­sues, know­ing as early as pos­si­ble is best. Fuzzing hap­pens af­ter code is merged. CI hap­pens when code is pushed. Runtime safety checks & ad­dress san­i­tizer hap­pens when code is run (hopefully in de­vel­op­ment, be­fore CI).

One com­mon way to re­duce this class of is­sue is to en­sure cleanup code is al­ways run ex­actly once for code that needs it. Zig is de­signed to be a sim­ple lan­guage with no hid­den con­trol flow, and so it prefers the ex­plicit de­fer key­word to run code at the end of a scope over C++’s im­plicit ~Destructor or Rust’s im­plicit Drop.

For Zig code, when ex­actly should we be run­ning the cleanup code? If we’re pass­ing the same *T to many dif­fer­ent func­tions, how do we know when it’s no longer ac­ces­si­ble and can be cleaned up? How does it work when some func­tions need to con­tinue to ref­er­ence the mem­ory af­ter the func­tion is called? Our cur­rent ap­proach is a mix of:

arena life­times, where the scope of when it’s ac­ces­si­ble is clear (parser state does­n’t es­cape the call­ing func­tion and so AST nodes are a good choice there)

ref­er­ence-count­ing

pay re­ally close at­ten­tion

Many pro­jects opt to an­swer these kinds of ques­tions through a style guide. TigerBeetle’s TigerStyle is an ex­am­ple in Zig and Google’s 31,000 word C++ style guide is an­other. The chal­lenge with style guides is en­force­ment. How do you make sure the style guide is fol­lowed? Historically, code re­view was the an­swer with best-ef­fort en­force­ment via lin­ters & sta­tic an­a­lyz­ers.

Having a rigid style guide with clear own­er­ship ex­pec­ta­tions ex­plic­itly spelled out in the type sys­tem was a real op­tion for Bun. Since Zig has no op­er­a­tor over­load­ing, we would likely end up with a lot of code look­ing some­thing like this:

fn foo(a_ptr: SharedPtr(TCPSocket)) !void { const a: *TCPSocket = a_ptr.get(); de­fer a_ptr.deref();

const b = try do_­some­thing_with_a(a); de­fer b.deref();

// … }

This is less er­gonomic than the Zig we ex­pect:

fn foo(a: *TCPSocket) !void { const b = try do_­some­thing_with_a(a); // … }

What about C/C++?

About 20% of Bun’s code is writ­ten in C++ and Bun em­beds sev­eral C/C++ li­braries:

JavaScriptCore, the JavaScript en­gine that pow­ers Safari

uWeb­Sock­ets & usock­ets - our HTTP/WebSocket server, and event loop

lsh­pack & lsquic - HPACK and HTTP/3 li­braries

BoringSSL, Google’s OpenSSL fork

SQLite

C++ in­stead of Zig would be a rea­son­able choice for Bun. We would get con­struc­tors & de­struc­tors. We could delete lots of ex­tern C” wrap­per code.

But, we would still be re­liant on style guides en­forced through code re­view, and even with ASAN, mem­ory cor­rup­tion and mem­ory leaks would still hap­pen.

Why Rust?

A large per­cent­age of bugs from that list are use-af­ter-free, dou­ble-free, and forgot to free” in an er­ror path. In safe Rust, these are com­piler er­rors and RAII-like au­to­matic cleanup with Drop. Compiler er­rors are a bet­ter feed­back loop than a style guide.

Historically, rewrites are a ter­ri­ble idea. Excluding com­ments, Bun is 535,496 lines of Zig. A rewrite in an­other lan­guage would take a small team of en­gi­neers a full year. It would mean freez­ing bug­fixes, se­cu­rity fixes or fea­ture de­vel­op­ment for that time. The least risky ap­proach to get­ting some­thing ship­pable would be a me­chan­i­cal port from Zig to Rust, with the min­i­mal num­ber of be­hav­ioral changes, us­ing the ex­act same test suite we al­ready use for test­ing Bun.

Fortunately, Bun’s own test suite is writ­ten in TypeScript which means it does­n’t de­pend on the run­time’s pro­gram­ming lan­guage.

A year of zero user-fac­ing im­pact is not a re­al­is­tic op­tion we could con­sider. So, en­force­ment through code-style to fix sta­bil­ity is­sues was our best bet, and was our plan when we added Rust-inspired smart point­ers to Bun’s code­base.

But hon­estly, I did­n’t want to do it. Homegrown smart point­ers of­fer worse er­gonom­ics than Rust, with none of the guar­an­tees.

What if, in­stead, I spend a week test­ing if Anthropic’s new model can rewrite Bun in Rust?

At first, I did­n’t ex­pect it to work. A few days in, a high % of the test suite started pass­ing and I saw how much the new Rust code matched up with the orig­i­nal Zig code­base. My opin­ion went from this is worth try­ing” to I’m go­ing to merge this”.

Claude, rewrite Bun in Rust.

There are a lot of ways to do a ter­ri­ble job of this. For ex­am­ple, prompt­ing Claude Rewrite Bun in Rust. Don’t make any mis­takes.” and then pray­ing it would work is not what I did.

Think about how a per­son would do this. The first big ques­tion is:

Incremental rewrite? Or, every­thing all at once?

In my ex­pe­ri­ence port­ing es­build’s tran­spiler from Go to Zig for the ini­tial ver­sion of Bun (without LLMs), every­thing all at once is bet­ter. An in­cre­men­tal rewrite adds tem­po­rary code that you hope gets deleted even­tu­ally, and would be painful in the short-medium term.

The sec­ond big ques­tion: how?

How do we keep Bun in Rust the same Bun as be­fore, with the same ar­chi­tec­ture, per­for­mance, and fea­ture-set while also get­ting the lan­guage fea­tures of Rust like the bor­row checker? How do we en­sure the team can still main­tain it af­ter the rewrite?

Do the rewrite that looks like we tran­spiled our Zig code to Rust. We can grad­u­ally refac­tor it to re­duce un­safe us­age and look more like id­iomatic Rust af­ter Bun v1.4 ships.

Those are the only two big ques­tions. Everything else is tac­tics.

Loops that write & re­view code

A lot of day-to-day en­gi­neer­ing work as soft­ware en­gi­neers can be over-sim­pli­fied into loops.

// Pseudocode, not real code: let task; while ((task = todoList.pop())) { const re­sult = task(); const feed­back = await Promise.all([review(result), re­view(re­sult)]); await ap­ply(feed­back, re­sult); }

A task has some con­text as­so­ci­ated with it (a Jira ticket, a GitHub is­sue, etc). The re­sult is the code you wrote to fix it. Code re­viewer(s) re­view the changes to check for re­gres­sions & cor­rect­ness. And then you ad­dress the feed­back.

I rewrote Bun in Rust us­ing about 50 dy­namic work­flows in Claude Code run con­tin­u­ously over the course of 11 days.

Each dy­namic work­flow was a loop like this - a work­flow for:

Generate a port­ing guide map­ping Zig pat­terns & types to Rust pat­terns & types

Mechanically port every .zig file to a .rs file, match­ing the PORTING.md and LIFETIMES.tsv

Fix every crate’s com­piler er­rors

Get sub­com­mands like bun test or bun build to work

Get every test in Bun’s en­tire test suite to pass

Several large refac­tors and cleanup passes

For most of those 11 days (and af­ter), I mon­i­tored work­flows - man­u­ally read­ing the out­puts to check for is­sues and bugs, and prompt­ing Claude to edit the loop to fix things.

How do you re­view a PR with +1 mil­lion lines added? How do you start to build the con­fi­dence needed to re­spon­si­bly merge large quan­ti­ties of LLM-authored code?

A lan­guage-in­de­pen­dent test suite with a mil­lion as­ser­tions, ad­ver­sar­ial code re­view and when some­thing does go wrong, fix­ing the process that gen­er­ates the code in­stead of hand-fix­ing the code.

Adversarial re­view

Adversarial re­view asks Claude (in a sep­a­rate con­text win­dow) to ex­haus­tively come up with rea­sons why the changes cre­ate bugs or do not work.

Split con­text win­dows

Usually with hu­mans, the per­son re­view­ing the code is not the per­son who au­thored the code. The per­son writ­ing the code wants to merge the code, which can bias their ac­tions to ship be­fore it’s ready.

Claude is the same way. The Claude that wrote the code wants the code to get ac­cepted. The Claude that re­views wants to find is­sues in the code.

1 im­ple­menter, 2 or more ad­ver­sar­ial re­view­ers per im­ple­menter. The re­view­er’s only job: find bugs & rea­sons why the code does not work. The im­ple­menter does­n’t re­view. The re­viewer does­n’t im­ple­ment.

✻ claude code · dy­namic work­flowad­ver­sar­ial re­view3 of the many bugs ad­ver­sar­ial re­view caught be­fore merge

bug 1 of 3 · the async close

✻claudeimplementer

its con­text: the .zig orig­i­nal, the port plan, its own rea­son­ing

Robostral Navigate: single-camera AI navigation | Mistral AI

mistral.ai

Thinking

Summary

Robostral Navigate is an 8B model that en­ables ro­bots to au­tonomously nav­i­gate com­plex en­vi­ron­ments us­ing only a sin­gle RGB cam­era, achiev­ing 76.6% suc­cess on un­seen R2R-CE bench­marks—out­per­form­ing multi-sen­sor ap­proaches while be­ing more ef­fi­cient. Built en­tirely in-house with sim­u­lated data and to­ken-ef­fi­cient tech­niques, it gen­er­al­izes across ro­bot types and adapts to real-world ob­sta­cles un­seen dur­ing train­ing. The model com­bines point­ing-based nav­i­ga­tion with re­in­force­ment learn­ing for con­tin­u­ous im­prove­ment, paving the way for uni­fied em­bod­ied AI in ro­bot­ics.

Today we’re in­tro­duc­ing Robostral Navigate, our first model built for em­bod­ied nav­i­ga­tion. It’s an 8B model that takes RGB im­ages and a plain-lan­guage in­struc­tion and moves a ro­bot through an en­vi­ron­ment:

Leave the lobby, walk through the cor­ri­dor, en­ter the sup­ply room, and stop to face the sec­ond shelf.”

To per­form such tasks, other mod­els of­ten em­ploy depth sen­sors, LiDAR, or sev­eral cam­eras work­ing to­gether. Robostral Navigate uses only one or­di­nary RGB cam­era and no depth sen­sors, yet still achieves 76.6% on R2R-CE (Room-to-Room in Continuous Environments) val­i­da­tion un­seen, the bench­mark for fol­low­ing in­struc­tions in en­vi­ron­ments held out of train­ing. Consequently, it beats the best sin­gle-cam­era ap­proach by 9.7 points and the best sys­tem us­ing depth or mul­ti­ple cam­eras by 4.5 points, de­spite us­ing nei­ther.

Our model is de­signed for ro­botic nav­i­ga­tion, en­abling ro­bots to au­tonomously nav­i­gate com­plex en­vi­ron­ments, in­clud­ing of­fices, res­i­den­tial and com­mer­cial build­ings, and out­door set­tings.

Robostral Navigate run­ning fully au­tonomously in one long-hori­zon in­struc­tion route through a work­ing of­fice.

This tech­nol­ogy un­locks nu­mer­ous ap­pli­ca­tions across man­u­fac­tur­ing, de­liv­ery, lo­gis­tics, and hos­pi­tal­ity, mak­ing it one of the most in-de­mand ca­pa­bil­i­ties for our cus­tomers to­day. Give Robostral Navigate one in­struc­tion and it com­pletes the en­tire task on its own, mov­ing through a live space full of peo­ple and ob­sta­cles it was never shown, ca­pa­ble of adapt­ing to any set­ting.

Highlights

State-of-the-art per­for­mance on R2R-CE

State-of-the-art per­for­mance on R2R-CE

79.4% Success Rate on val­i­da­tion seen 76.6% Success Rate on val­i­da­tion un­seen

79.4% Success Rate on val­i­da­tion seen

79.4% Success Rate on val­i­da­tion seen

76.6% Success Rate on val­i­da­tion un­seen

76.6% Success Rate on val­i­da­tion un­seen

Operates from a sin­gle RGB cam­era, with no LiDAR or depth sen­sors

Operates from a sin­gle RGB cam­era, with no LiDAR or depth sen­sors

8B model, built in-house and trained en­tirely in sim­u­la­tion

8B model, built in-house and trained en­tirely in sim­u­la­tion

Runs on wheeled, legged, and fly­ing ro­bots, and gen­er­al­izes across ro­bot sizes

Runs on wheeled, legged, and fly­ing ro­bots, and gen­er­al­izes across ro­bot sizes

Robust to dif­fer­ences in cam­era in­trin­sics

Robust to dif­fer­ences in cam­era in­trin­sics

Token-efficient train­ing via pre­fix-caching

Token-efficient train­ing via pre­fix-caching

Navigation via point­ing

Given a task and a his­tory of ob­ser­va­tions, Robostral Navigate pre­dicts where the ro­bot should move next via point­ing: it in­fers the im­age co­or­di­nates of the tar­get lo­ca­tion in the ro­bot’s cur­rent cam­era view, to­gether with the de­sired ori­en­ta­tion upon ar­rival. Unlike com­mands re­ly­ing on met­ric dis­place­ments, point­ing makes the pol­icy nat­u­rally ro­bust to changes in cam­era in­trin­sics and world scale.

However, this method can­not han­dle cases where the tar­get lo­ca­tion lies out­side the cur­rent field of view. When point­ing does not ap­ply, the model falls back to dis­place­ments in the ro­bot’s lo­cal co­or­di­nate frame, such as:

Move 2 me­ters for­ward, 1.5 me­ters to the left, and turn 25 de­grees left.”

Built from the ground up

Robostral Navigate is built en­tirely in-house and does not rely on ex­ist­ing open-source VLMs.

The model is ini­tial­ized from our vi­sion-lan­guage model spe­cial­ized for ground­ing tasks such as point­ing, count­ing, and ob­ject lo­cal­iza­tion. Navigation emerges as a nat­ural ex­ten­sion of these ca­pa­bil­i­ties: once it un­der­stands where things are, it learns how to move.

We built an ef­fi­cient data gen­er­a­tion pipeline en­tirely in sim­u­la­tion. This en­abled rapid it­er­a­tion on the data, re­sult­ing in a dataset of ap­prox­i­mately 400,000 tra­jec­to­ries col­lected across 6,000 scenes.

Efficient su­per­vised train­ing

A key in­gre­di­ent of Robostral Navigate is an ef­fi­cient train­ing al­go­rithm based on pre­fix-caching. Using a tree-based at­ten­tion-mask­ing strat­egy, our method com­presses an en­tire episode into a sin­gle se­quence, en­abling train­ing on all time steps in a sin­gle for­ward pass while pre­vent­ing in­for­ma­tion leak­age be­tween time steps.

Compared to train­ing with one sam­ple per time step, our ap­proach re­duces the num­ber of train­ing to­kens by 22× while pre­serv­ing all of the learn­ing sig­nals. In prac­tice, this method trans­forms train­ing runs that would take months into runs that com­plete in days.

Online re­in­force­ment learn­ing

We lever­age our knowl­edge of post-train­ing LLMs at scale, us­ing on­line re­in­force­ment learn­ing, to boost the per­for­mance of Robostral Navigate. After the su­per­vised train­ing stage, we fur­ther im­prove the mod­el’s per­for­mance us­ing CISPO, an on­line re­in­force­ment learn­ing al­go­rithm. This en­ables the model to learn from trial and er­ror, re­cover from fail­ures, and ac­quire ex­ploratory be­hav­iors, ef­fec­tively mit­i­gat­ing the dis­tri­b­u­tion shift is­sue of vanilla be­hav­ior cloning. This alone im­proved the suc­cess rate by 3.2%. We are not see­ing any plateau­ing, so we are con­fi­dent that more train­ing and more ex­per­i­ments will con­tinue to push this num­ber up.

What’s Next

Robostral Navigate is only the first step to­ward a uni­fied em­bod­ied agent.

We be­lieve nav­i­ga­tion is a foun­da­tional ca­pa­bil­ity for gen­eral-pur­pose ro­bot­ics. By com­bin­ing large-scale sim­u­la­tion, ef­fi­cient train­ing, and strong ground­ing pri­ors, Robostral Navigate demon­strates that state-of-the-art em­bod­ied nav­i­ga­tion can be achieved with a com­pact model and a sin­gle RGB cam­era.

Start your jour­ney to em­bod­ied fron­tier AI, talk with our team.

BTW, we’re hir­ing!

The re­lease of our nav­i­ga­tion mod­els marks a sig­nif­i­cant step for­ward, but our jour­ney is far from over. Our am­bi­tion is to en­able ro­bots to au­tonomously nav­i­gate com­plex en­vi­ron­ments—of­fices, homes, com­mer­cial build­ings, and out­door spaces—and there’s a lot more work to do. We are ac­tively ex­pand­ing our ro­bot­ics team and look­ing for tal­ented re­search sci­en­tists and en­gi­neers who share our am­bi­tion.

If you’re in­ter­ested in join­ing us on our mis­sion to bring seam­less nav­i­ga­tion to ro­bots every­where, we wel­come your ap­pli­ca­tions to join our team!

By Théo Cachet, Arjun Majumdar, Srijan Mishra, Thomas Chabal, Chris Bamford, Elliot Chane-Sane, Benjamin Tibi, Ludovic Ho Fuh, Olivier Duchenne - AI Science Robotics

Cloudflare Drop

www.cloudflare.com

🐀 ESCAPE THE RAT RACE

www.abeyk.com

A FAANG™ Life Simulator

one tap = one quar­ter of your life · feat. MILTON

daily run = every­one gets the same cursed time­line to­day. com­pare es­capes.

not af­fil­i­ated with any tril­lion-dol­lar com­pany, al­legedly.

mil­ton ↑

AGE 22Y1 · Q1

🏝️ FREEDOM (quit-forever fund)0%

📈 per­for­mance50

🚀 trac­tion0

🔥 burnout10

NET WORTH$0k

COMP / YR$190k

we are so back

GO HOME

Form HR-1099-RAT · Exit Interview · —

one square = one year of your life:

Post on 𝕏

EU now one step away from reviving private message scanning rules

cyberinsider.com

The European Parliament has ap­proved an ur­gent pro­ce­dure to fast-track leg­is­la­tion that would re­vive the EUs ex­pired Chat Control 1.0” rules.

This de­vel­op­ment sets up a de­ci­sive vote on July 9 over whether on­line plat­forms may once again be al­lowed to vol­un­tar­ily scan pri­vate user com­mu­ni­ca­tions for child sex­ual abuse ma­te­r­ial (CSAM).

MEPs voted 331 in fa­vor and 304 against us­ing the ur­gency pro­ce­dure, al­low­ing Parliament to by­pass the usual com­mit­tee stage. The pro­ce­dural vote does not it­self re­in­state the law but ac­cel­er­ates con­sid­er­a­tion of a pro­posal that would ef­fec­tively re­store the tem­po­rary le­gal frame­work that ex­pired in April.

STRASBOURG: EU Chat Control 👁️‍🗨️Just a few mo­ments ago, the European Parliament ap­proved the ur­gent pro­ce­dure for the Chat Control ex­ten­sion (331 in favour, 304 against). On Thursday, MEPs will vote on whether to al­low on­line plat­forms to scan pri­vate mes­sages. pic.twit­ter.com/​vB­gyvFCXYl— Sebastián Lukomski (@lukomski_sebito) July 7, 2026

STRASBOURG: EU Chat Control 👁️‍🗨️

Just a few mo­ments ago, the European Parliament ap­proved the ur­gent pro­ce­dure for the Chat Control ex­ten­sion (331 in favour, 304 against).

On Thursday, MEPs will vote on whether to al­low on­line plat­forms to scan pri­vate mes­sages. pic.twit­ter.com/​vB­gyvFCXYl

The leg­is­la­tion in ques­tion is sep­a­rate from the EUs long-run­ning ne­go­ti­a­tions over the pro­posed Child Sexual Abuse Regulation (CSAR), com­monly known as Chat Control 2.0.” The co­ex­is­tence of two dif­fer­ent leg­isla­tive files has led to con­fu­sion, as one con­cerns the re­vival of an ex­pired tem­po­rary mea­sure while the other seeks to es­tab­lish a per­ma­nent frame­work for de­tect­ing and re­port­ing CSAM.

The tem­po­rary reg­u­la­tion, for­mally Regulation (EU) 2021/1232, orig­i­nally cre­ated an ex­emp­tion to the ePri­vacy Directive al­low­ing providers to vol­un­tar­ily scan pri­vate com­mu­ni­ca­tions for CSAM. The ex­emp­tion ap­plied pri­mar­ily to ser­vices such as Gmail, Facebook Messenger, Instagram Messenger, Skype, Snapchat, iCloud Mail, and Xbox mes­sag­ing, while end-to-end en­crypted ser­vices were gen­er­ally un­af­fected un­less providers chose to im­ple­ment client-side scan­ning.

As pre­vi­ously re­ported, the European Parliament voted in March to re­ject an ex­ten­sion of the tem­po­rary dero­ga­tion af­ter ne­go­ti­a­tions with the Council col­lapsed. The reg­u­la­tion sub­se­quently ex­pired on April 4, 2026, re­mov­ing the le­gal ba­sis that many plat­forms had re­lied upon for vol­un­tary scan­ning within the scope of the ePri­vacy Directive.

Since then, how­ever, the Council of the European Union has sought to bring the mea­sure back through what is for­mally pre­sented as a new reg­u­la­tion con­tain­ing sub­stan­tially the same pro­vi­sions. Former Pirate Party MEP Patrick Breyer, a long-time op­po­nent of the pro­posal, de­scribes the move as an un­prece­dented at­tempt to res­ur­rect leg­is­la­tion that Parliament had al­ready re­jected.

🇬🇧Narrow ma­jor­ity for ur­gency vote on re­in­stat­ing #ChatControl 1.0 mass scans.331 +304 – 11 oA dark day for pri­vacy & democ­racy. On Thursday, there will be the vote on the sub­stance. Only an ab­solute ma­jor­ity can stop it. 🚨https://​https://​t.co/​H0qG­zofi7X— Patrick Breyer #JoinMastodon (@echo_pbreyer) July 7, 2026

🇬🇧Narrow ma­jor­ity for ur­gency vote on re­in­stat­ing #ChatControl 1.0 mass scans.331 +304 – 11 oA dark day for pri­vacy & democ­racy. On Thursday, there will be the vote on the sub­stance. Only an ab­solute ma­jor­ity can stop it. 🚨https://​https://​t.co/​H0qG­zofi7X

According to Breyer’s time­line, the Council ap­proved its ne­go­ti­at­ing po­si­tion on July 2 be­fore Parliament agreed this week to con­sider the pro­posal un­der an ex­pe­dited pro­ce­dure.

The bind­ing vote is sched­uled for Thursday, July 9. Under the pro­ce­dure, op­po­nents would need an ab­solute ma­jor­ity of all Members of the European Parliament, 361 votes, to re­ject or amend the pro­posal. If that thresh­old is not reached, the Council’s text is ex­pected to pro­ceed with­out the Parliament im­pos­ing ad­di­tional safe­guards.

The re­vived pro­posal should not be con­fused with Chat Control 2.0, the per­ma­nent Child Sexual Abuse Regulation that has been un­der ne­go­ti­a­tion since 2022. That pro­posal re­mains stalled af­ter five rounds of tri­logue ne­go­ti­a­tions be­tween Parliament, the Council, and the European Commission.

The main point of dis­agree­ment re­mains whether providers should be per­mit­ted or re­quired to con­duct broad, sus­pi­cion­less scan­ning of pri­vate com­mu­ni­ca­tions, par­tic­u­larly on end-to-end en­crypted ser­vices. The Parliament’s ne­go­ti­at­ing po­si­tion lim­its scan­ning to users or groups specif­i­cally sus­pected of child sex­ual abuse and re­quires ju­di­cial au­tho­riza­tion, while the Council has con­tin­ued ad­vo­cat­ing broader risk-mit­i­ga­tion oblig­a­tions and vol­un­tary de­tec­tion mea­sures that crit­ics ar­gue would still en­cour­age mass scan­ning.

The Council’s own Legal Service re­port­edly warned in June that even voluntary” gen­er­al­ized scan­ning of com­mu­ni­ca­tions may con­flict with Article 7 of the EU Charter of Fundamental Rights un­less sup­ported by rea­son­able sus­pi­cion and prior ju­di­cial au­tho­riza­tion.

As a re­sult, the EU is now pur­su­ing two par­al­lel leg­isla­tive tracks. One seeks to tem­porar­ily re­store the ex­pired vol­un­tary scan­ning regime, while the other con­tin­ues ne­go­ti­a­tions on a per­ma­nent law that could re­shape how on­line plat­forms de­tect CSAM across the European Union.

Thursday’s par­lia­men­tary vote will de­ter­mine whether the tem­po­rary frame­work re­turns while ne­go­ti­a­tions over the much broader and more con­tro­ver­sial per­ma­nent reg­u­la­tion con­tinue.

If you liked this ar­ti­cle, be sure to fol­low us on X/Twitter and also LinkedIn for more ex­clu­sive con­tent.

To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".

10HN is also available as an iOS App

If you visit 10HN only rarely, check out the the best articles from the past week.

Visit pancik.com for more.