<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/we-compiled-our-typescript-parser-to-wasm-1mn76cyyw" -->

---
title: We compiled our TypeScript parser to WASM | daily.dev
description: Encore's TypeScript parser, written in Rust and built on SWC, was compiled to WebAssembly so it can run in the browser. The key challenge was replacing...
canonical: https://daily.dev/posts/we-compiled-our-typescript-parser-to-wasm-1mn76cyyw
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: We compiled our TypeScript parser to WASM | daily.dev
og:description: Encore's TypeScript parser, written in Rust and built on SWC, was compiled to WebAssembly so it can run in the browser. The key challenge was replacing...
og:url: https://daily.dev/posts/we-compiled-our-typescript-parser-to-wasm-1mn76cyyw
og:image: https://api.daily.dev/og/posts/1mn76CyYw.png
og:image:alt: We compiled our TypeScript parser to WASM
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# We compiled our TypeScript parser to WASM

**[Encore](https://daily.dev/sources/encore-blog)** · 7 min read · 39 upvotes · 1 comments

## Summary

Encore's TypeScript parser, written in Rust and built on SWC, was compiled to WebAssembly so it can run in the browser. The key challenge was replacing filesystem dependencies (directory traversal, tsconfig.json reading, SQL migration parsing) with in-memory equivalents, achieved via Cargo feature flags that gate all native OS interactions behind a `native` feature. The SDK is baked directly into the WASM binary at build time. The result is a playground at tsparser.encore.dev where users can reproduce parser bugs by pasting code snippets and sharing links, running the exact same parser binary used in the CLI and CI.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://encore.dev/blog/typescript-parser-wasm>

## Questions this post answers

### How do you handle filesystem-dependent Rust code when compiling to WebAssembly for the browser?

Gate filesystem- and subprocess-dependent functionality behind a Cargo feature flag so it compiles out entirely for the WASM target. Encore's TypeScript parser puts directory traversal, node_modules resolution, and SQL migration parsing behind a 'native' feature that is disabled for the WASM build, while individual functions get WASM-specific counterparts (e.g., migration parsing returns an empty list instead of reading a folder) using #[cfg(target_arch = "wasm32")] checks.

_daily.dev surfaces posts on shipping Rust code to WASM for developers hitting the same filesystem gap._

### How can I let a WASM-compiled parser resolve imports without real filesystem access?

Build an in-memory file resolver that answers import lookups from a set of files passed in by the caller instead of reading disk. Encore's browser parser resolves relative imports, encore.dev imports, and bare package names against files handed to it as JSON, registering each package.json so bare imports find their entry point the same way node_modules resolution would locally.

_developers wiring dependency resolution into browser tools can track approaches like this via daily.dev._

### How do you keep a WASM build in sync with a specific SDK version it depends on?

Bake the SDK's source files directly into the compiled binary rather than trusting whatever version a caller provides. Encore generates an array of embedded TypeScript files and package.json contents at build time using include_str! for every file in its encore.dev SDK, then strips any user-supplied encore.dev files and substitutes the bundled ones before parsing, guaranteeing the parser always matches the SDK version it was built against.

_daily.dev helps engineers dealing with SDK-version coupling in compiled tools find similar patterns._

## Similar posts on daily.dev

- [Rewriting our Rust WASM Parser in TypeScript](https://daily.dev/posts/rewriting-our-rust-wasm-parser-in-typescript-l5hpi7vvy) · Hacker News · 19 upvotes · 1 comments
- [Vercel Labs Ships scriptc, a TypeScript-to-Native Compiler That Leaves the JavaScript Engine Behind](https://daily.dev/posts/vercel-labs-ships-scriptc-a-typescript-to-native-compiler-that-leaves-the-javascript-engine-behind-mp2rtartc) · InfoQ · 7 upvotes · 0 comments
- [Supporting native Rust in Workers with the new Emscripten target for wasm-bindgen](https://daily.dev/posts/supporting-native-rust-in-workers-with-the-new-emscripten-target-for-wasm-bindgen-fqeuggppz) · Cloudflare · 45 upvotes · 5 comments
- [Encore for Rust](https://daily.dev/posts/encore-for-rust-iurebtf6y) · Encore · 46 upvotes · 3 comments

---

Tags: [#typescript](https://daily.dev/tags/typescript), [#rust](https://daily.dev/tags/rust), [#webassembly](https://daily.dev/tags/webassembly)

[View this post on daily.dev](https://daily.dev/posts/we-compiled-our-typescript-parser-to-wasm-1mn76cyyw)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"We compiled our TypeScript parser to WASM","url":"https://daily.dev/posts/we-compiled-our-typescript-parser-to-wasm-1mn76cyyw","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/we-compiled-our-typescript-parser-to-wasm-1mn76cyyw"},"datePublished":"2026-07-15T13:26:56.476Z","dateModified":"2026-09-14T08:15:01.099Z","description":"Encore's TypeScript parser, written in Rust and built on SWC, was compiled to WebAssembly so it can run in the browser. The key challenge was replacing...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/7876f9d32a0846fd4c07a1a460129ba7?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/7876f9d32a0846fd4c07a1a460129ba7?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Encore","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Encore","logo":"https://media.daily.dev/image/upload/s--8Bz0eBFn--/f_auto,q_auto/v1780213589/logos/encore-blog?_a=BAMAMiWQ0","url":"https://daily.dev/sources/encore-blog"},"commentCount":1,"discussionUrl":"https://daily.dev/posts/we-compiled-our-typescript-parser-to-wasm-1mn76cyyw","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":39},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"typescript,rust,webassembly","timeRequired":"PT7M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Encore","item":"https://daily.dev/sources/encore-blog"},{"@type":"ListItem","position":3,"name":"We compiled our TypeScript parser to WASM"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/we-compiled-our-typescript-parser-to-wasm-1mn76cyyw#faq","mainEntity":[{"@type":"Question","name":"How do you handle filesystem-dependent Rust code when compiling to WebAssembly for the browser?","acceptedAnswer":{"@type":"Answer","text":"Gate filesystem- and subprocess-dependent functionality behind a Cargo feature flag so it compiles out entirely for the WASM target. Encore's TypeScript parser puts directory traversal, node_modules resolution, and SQL migration parsing behind a 'native' feature that is disabled for the WASM build, while individual functions get WASM-specific counterparts (e.g., migration parsing returns an empty list instead of reading a folder) using #[cfg(target_arch = \"wasm32\")] checks. daily.dev surfaces posts on shipping Rust code to WASM for developers hitting the same filesystem gap."}},{"@type":"Question","name":"How can I let a WASM-compiled parser resolve imports without real filesystem access?","acceptedAnswer":{"@type":"Answer","text":"Build an in-memory file resolver that answers import lookups from a set of files passed in by the caller instead of reading disk. Encore's browser parser resolves relative imports, encore.dev imports, and bare package names against files handed to it as JSON, registering each package.json so bare imports find their entry point the same way node_modules resolution would locally. developers wiring dependency resolution into browser tools can track approaches like this via daily.dev."}},{"@type":"Question","name":"How do you keep a WASM build in sync with a specific SDK version it depends on?","acceptedAnswer":{"@type":"Answer","text":"Bake the SDK's source files directly into the compiled binary rather than trusting whatever version a caller provides. Encore generates an array of embedded TypeScript files and package.json contents at build time using include_str! for every file in its encore.dev SDK, then strips any user-supplied encore.dev files and substitutes the bundled ones before parsing, guaranteeing the parser always matches the SDK version it was built against. daily.dev helps engineers dealing with SDK-version coupling in compiled tools find similar patterns."}}]}
```

