Skip to content

feat(metadata): add ns metadata trim - #6203

Draft
NathanWalker wants to merge 2 commits into
mainfrom
feat/metadata-trim
Draft

NathanWalker wants to merge 2 commits into
mainfrom
feat/metadata-trim

Conversation

@NathanWalker

@NathanWalker NathanWalker commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds ns metadata trim, which reduces native API metadata to what an app's emitted JavaScript uses, plus the types those APIs depend on.

ns metadata trim <platform> <bundle...>
  collect declared rules (native-api-usage.json, --keep)
  toolchain.analyze    bundle + kept rules -> filter patterns (the runtime's own analyzers)
  stop if usage can't be bounded (dynamic global access, eval)
  toolchain.generate   patterns -> metadata (Apple; Gradle does this on Android)
  toolchain.install    embed into NativeScript.framework, or write whitelist.mdg

It builds on metadata filtering rather than replacing it: native-api-usage.json rules from the app and its plugins are merged with what the analysis finds.

The command is host-neutral. It takes a bundle path, so it doesn't assume a NativeScript project layout. Scope, how it works and how other hosts adopt it are in the RFC: NativeScript/rfcs#62.

lib/
├── commands/metadata-trim.ts
├── definitions/metadata-trim-service.d.ts   # IMetadataToolchain, the extension point
└── services/
    ├── metadata-trim-service.ts             # analyze -> generate -> install
    └── metadata-trim/
        ├── apple-toolchain.ts               # ns-metadata-symbols + objc-metadata-generator
        ├── android-toolchain.ts             # the runtime's seed.js, then Gradle
        ├── declared-rules.ts                # merges native-api-usage.json rules
        └── macho-metadata.ts                # replaces and shrinks __objc_metadata

Related fix on the generator: NativeScript/runtimes@cb26a2b.

Evidence

Run on a TSX app embedding NativeScript in nsh: macOS 26, iOS 26.5 simulator, Android 16 emulator. Not yet run on physical devices or against a standard ns project.

macOS iOS Android
Before: metadata 4.7 MB 4.6 MB 2.9 MB
After: metadata 0.67 MB 0.83 MB 0.81 MB
Before: framework, compressed 2.36 MB 1.84 MB n/a
After: framework, compressed 0.95 MB 0.84 MB n/a
  • A native-view check (creation, layout, both directions of a signal binding, unmount and remount) passes 7/7 on all three platforms running on trimmed metadata.
  • npx vitest run: 2167 passed, 9 skipped, including new tests for the Mach-O rewrite and both toolchains.
  • A bundle with dynamic global access stops with "Nothing was trimmed" and generates nothing.
  • native-api-usage.json on a project fixture: the app's whitelist and blacklist and a plugin's uses all reach the generator, and whitelist-plugins-usages: false drops the plugin's entry.
  • Android through Gradle: a uses entry adds WebView and a blacklist entry removes Build.VERSION. Blacklisting a type a kept API needs fails the build and names it.

Merge Danger

Door: two-way

Additive. It introduces one new command, with its options scoped to that command. Nothing calls it from prepare or build.

Blast Radius: additive

Only people who run the new command are affected. A trimmed app that reaches an API the analysis can't see fails at run time in that code path, which is why this is opt-in and the RFC covers the rollout.

…n app uses

Analyzes an app's emitted JavaScript with the runtime's own tools and
generates metadata for what it references plus the types those depend on.

On Apple platforms the result can be embedded into a copy of
NativeScript.framework, shrinking the binary. On Android it writes the
whitelist Gradle consumes with -PnsFilterMetadata.
@coderabbitai

coderabbitai Bot commented Nov 9, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Declared rules are merged with what the bundle analysis finds, following
the same whitelist-plugins-usages semantics as ns prepare. Projects are
read automatically for iOS and Android; other hosts pass --native-api-usage.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant