Skip to content
| Marketplace
Sign in
Visual Studio Code>Visualization>Basalt — React Native Visual EditorNew to Visual Studio Code? Get it now.
Basalt — React Native Visual Editor

Basalt — React Native Visual Editor

Basalt

|
2 installs
| (0) | Free
Expo phone preview, visual edit, and Figma-to-React-Native merge for VS Code and Cursor
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Basalt

Expo phone preview, visual edit, and Figma merge for VS Code and Cursor.

Basalt is a standalone extension — no separate IDE required. Open your Expo app, preview it in a device frame, edit copy in place, and merge Figma designs with Cursor AI.

Features

Feature Description
Preview Live Expo web build in an iPhone or iPad frame
Inspect Hover elements, see layout metrics, open source
Edit Double-click text, edit inline, auto-save to source
Figma Paste a design URL → merge to React Native via Cursor chat
Undo ⌘Z / Ctrl+Z reverts preview and source edits
Screen picker Dropdown to jump between routes / screens (auto-detected)

Screen picker (universal)

Basalt discovers screens from your project automatically:

  1. basalt.preview.json in the Expo root (optional, highest priority)
  2. Expo Router — files under app/
  3. React Navigation — Stack.Screen / Tab.Screen names + linking paths
  4. TypeScript Screen unions — e.g. type Screen = 'home' | 'settings'
  5. src/screens/ and src/pages/ file names

Use the Screens dropdown in the preview header after Metro starts.

Custom manifest (basalt.preview.json)

See examples/basalt.preview.json in this repo. Each screen can use:

  • "path": "/settings" — Expo Router / web path
  • "query": { "basaltPreview": "paywall" } — deep link via injected screen navigation (no app code required for most React apps)

Basalt injects a screen navigation bridge into the preview iframe (via the Metro proxy). For apps with Expo Router or path-based routing, path/hash entries work natively. For state-machine screens (type Screen = 'home' | 'settings'), the bridge applies navigation through React at runtime — no changes to your app repo.

Optional: apps can also listen for basalt:previewNavigate or read ?basaltPreview= themselves for tighter control.

Requirements

  • VS Code 1.85+ or Cursor
  • Node.js on your PATH (npx for Metro)
  • An Expo project (expo in package.json)

Quick start

  1. Install the extension (VSIX or marketplace).
  2. Open your Expo app folder as the workspace.
  3. Run Basalt: Open Phone Preview from the command palette, or click the phone icon in the editor toolbar. The preview opens in a tab beside your code.
  4. Click ▶ Start Preview and wait for Metro (first run may take 1–3 minutes).

Tabs

  • Preview — device frame, inspect, and edit controls
  • Figma — paste https://www.figma.com/design/… → Merge to RN opens Cursor chat with the merge prompt

For Figma merge, also add the basalt-fig-merge skill to your Expo project (copy from .cursor/skills/basalt-fig-merge/ in this repo into your app’s .cursor/skills/).

Commands

Command Action
Basalt: Open Phone Preview Open the preview sidebar
Basalt: Start Preview Start Metro and load the app
Basalt: Stop Preview Stop Metro
Basalt: Open Figma Tab Open preview and switch to Figma
Basalt: Show Preview Log Open the output log
Basalt: Enable Source & Bound-Edit Injection Enable dev-only precise source and runtime item provenance

Settings

Setting Default Description
basalt.expoProjectPath "" Fallback Expo root if not in workspace
basalt.autoStartPreview false Auto-open preview when Expo is detected
basalt.itemIdProperty "id" Stable object-key property used to edit state-selected list items (for example uuid)

Edit mode tips

  • Switch to Edit, double-click text, type, press Enter (or click outside) to save.
  • ⌘Z / Ctrl+Z undoes preview + file edits.
  • Success toasts only appear when the file actually saved. If Basalt cannot resolve a binding, it says so — it will not pretend.

Supported text-edit patterns (honest scope)

Basalt edits source, not the running app’s memory. It follows language shapes that show up in many Expo/RN apps — not your file names, folder layout, or product domain.

Works today

Pattern What Basalt does
Literal JSX / props <Text>Hello</Text>, title="…", config strings
List row binding FlatList / SectionList data={ARR} + {item.field} / `${item.field}` → import of ARR → that object (by React list key when available)
Detail via .find() const row = ARR.find(…) + {row.field} → import of ARR → unique object whose field matches the displayed value
State-selected detail/modal setSelected(item) from .map / renderItem, then {selected.field} → dev-only runtime identity stamp → the exact source object
Open in Source Uses injected source + TypeScript when possible

Does not reliably work yet

Pattern What happens
Redux / Zustand / React Query / context-only data Usually cannot land on a literal — Basalt should refuse with an honest error
Values that exist only on a server (no literal in the repo) Cannot “save to source”
Deep prop drilling / renamed bindings TS can’t follow May fail; use Cmd+click and edit manually
Ambiguous matches without runtime item identity Refuses rather than guessing the wrong row

State-selected edits require Basalt's dev-only source injection. Existing configured projects are refreshed automatically before Metro starts; the generated code is disabled in production builds. For collections keyed by something other than id, set basalt.itemIdProperty and restart Preview.

What we will not do

  • Hardcode paths or app names (cars.ts, a specific screen file, one customer’s repo)
  • Grep the whole project for name: / price: until something sticks
  • Show “Saved to source” when nothing was written

As coverage grows, new fixes target more of these shapes (same in every app), not tuning for one project.

Figma merge tips

  • Use a figma.com URL, not a local .fig file (MCP reads cloud designs).
  • Run merge from your Expo app workspace, not the extension repo.
  • Enable Figma MCP in Cursor.
  • In chat: @basalt /fig_merge or use Merge to RN from the Figma tab.

Development

npm install
npm run compile
npm run package   # creates basalt-preview-X.X.X.vsix

Press F5 in this repo to launch an Extension Development Host. Disable any installed copy of Basalt while debugging.

License

MIT

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft