RepoPilot

1Password/typeshare

Typeshare is the ultimate tool for synchronizing your type definitions between Rust and other languages for seamless FFI.

Healthy

Healthy across the board

HealthyDependency

Permissive license, no critical CVEs, actively maintained — safe to depend on.

HealthyFork & modify

Has a license, tests, and CI — clean foundation to fork and modify.

HealthyLearn from

Documented and popular — useful reference codebase to read through.

HealthyDeploy as-is

No critical CVEs, sane security posture — runnable as-is.

  • Scorecard: default branch unprotected (0/10)
  • Last commit 1d ago
  • 12 active contributors
  • Distributed ownership (top contributor 39% of recent commits)
  • Apache-2.0 licensed
  • CI configured
  • Tests present

Computed from maintenance signals — commit recency, contributor breadth, bus factor, license, CI, tests, cross-checked against OpenSSF Scorecard

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/1password/typeshare)](https://repopilot.app/r/1password/typeshare)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card

This card auto-renders when someone shares https://repopilot.app/r/1password/typeshare on X, Slack, or LinkedIn.

Ask AI about 1password/typeshare

Grounded in the actual source code. Pick a starter question or write your own.

Or write your own question →

Onboarding doc

Onboarding: 1Password/typeshare

Generated by RepoPilot · 2026-06-24 · Source

🎯Verdict

GO — Healthy across the board

  • Last commit 1d ago
  • 12 active contributors
  • Distributed ownership (top contributor 39% of recent commits)
  • Apache-2.0 licensed
  • CI configured
  • Tests present
  • ⚠ Scorecard: default branch unprotected (0/10)

<sub>Computed from maintenance signals — commit recency, contributor breadth, bus factor, license, CI, tests, cross-checked against OpenSSF Scorecard</sub>

TL;DR

Typeshare is a Rust code generator that parses Rust type definitions and automatically transpiles them into Swift, Go, Python, Kotlin, Scala, and TypeScript, eliminating manual FFI type synchronization. It uses procedural macros (typeshare-annotation crate) and a dedicated parser (core crate) to extract and translate types while respecting language-specific conventions and constraints, reducing the friction and bugs that come from manually maintaining duplicate type definitions across language boundaries. Monorepo with four crates: annotation/ (procedural macros for @typeshare annotations), core/ (parser and type extraction from Rust AST, exports language writers), cli/ (TOML config in cli/data/tests/*.toml and entry point in cli/src/main.rs), and lib/ (public SDK). Language-specific code generation logic is modular—each language has a writer that translates core AST to target syntax.

👥Who it's for

Backend engineers and systems architects building polyglot applications with Rust FFI layers who need to share type contracts between Rust and multiple client/service languages (iOS Swift teams, Go microservices, Python data services, Kotlin Android apps, etc.) without manual synchronization.

🌱Maturity & risk

Actively maintained and production-ready. The workspace structure (annotation, cli, core, lib crates) with published artifacts on crates.io, organized CI/CD in .github/workflows/ (audit.yml, ci.yml, release.yml), and comprehensive test data in core/data/tests/ demonstrate maturity. Multiple language target support and semantic versioning on crates.io indicate this is battle-tested.

Low-to-moderate risk. Single primary language (Rust) reduces surface area, but the transpilation logic across 6+ target languages is complex—any parser bug propagates across all outputs. Dependencies are minimal (log, flexi_logger only in workspace deps), reducing supply-chain risk. The test suite (core/data/tests/ with example input/output pairs for each language) provides good coverage, but breaking changes in procedural macro semantics could affect downstream consumers.

Active areas of work

Active CI/CD pipeline runs on push (ci.yml), audit checks dependencies regularly (audit.yml), and release automation exists (release.yml). Test-driven development evident from core/data/tests/ directory which mirrors real-world type scenarios (algebraic_enum_decorator, anonymous_struct_with_rename, constraints). No visible breaking-change commits in the snippet, suggesting focus on stability and incremental feature additions.

🚀Get running

git clone https://github.com/1Password/typeshare.git
cd typeshare
cargo build
cargo test --all

Daily commands: This is a CLI tool, not a service. Run it with: bash cargo run --bin typeshare -- --input /path/to/types.rs --output /path/to/output --lang swift Or install via cargo and invoke globally: ```bash cargo install typeshare-cli typeshare --help

🗺️Map of the codebase

  • cli/src/main.rs — Entry point for the typeshare CLI tool; orchestrates parsing, configuration, and code generation across all supported languages.
  • core/Cargo.toml — Core transformation engine dependencies; defines the foundation for AST parsing and language-specific code generation.
  • annotation/src/lib.rs — Proc-macro definitions for #[typeshare] attributes that drive the annotation-based API for marking Rust types for export.
  • cli/src/config.rs — Configuration parsing from TOML files; critical for understanding language-specific output settings and type mappings.
  • cli/src/writer.rs — Polymorphic code generation interface that routes transformations to language-specific backends (Swift, Kotlin, TypeScript, etc.).
  • cli/src/parse.rs — Rust source parsing and AST construction; bridges raw Rust code to the internal type representation used by generators.

🧩Components & responsibilities

  • Annotation (proc-macro crate) (syn, quote, proc-macro) — Provides #[typeshare] and related attributes; validates that only exportable types (structs, enums) are marked.
    • Failure mode: Invalid attribute usage (e.g., #[typeshare] on functions) or macro expansion panic; caught at Rust compile time.
  • CLI (main.rs, args.rs, config.rs) (clap, toml-rs, structopt-like argument parsing) — Parses command-line arguments, loads TOML configuration, orchestrates parsing and code generation pipeline.
    • Failure mode: Missing config file, invalid TOML, unsupported language target; user-facing errors with helpful messages.
  • Parser (cli/src/parse.rs) (syn, proc-macro2) — Converts Rust source files into a language-agnostic internal AST; extracts types, fields, generics, and attributes.
    • Failure mode: Syntax errors in Rust input; parse errors are reported with line numbers; unsupported Rust features (e.g., HRTB, complex macros) silently ignored or cause parse failures.
  • Writer (cli/src/writer.rs) (File I/O, language-specific modules) — Routes parsed AST to language-specific code generators; aggregates outputs and writes files to disk.
    • Failure mode: Disk write failures, permission errors, or generator panic; could leave partial/corrupted output files.
  • Language Backends (Swift, Kotlin, TypeScript, Go, Python, Scala generators) (String templating, language-specific idioms) — Each backend traverses the AST and emits idiomatic code for its target language, respecting constraints and decorators.
    • Failure mode: Unsupported type constructs (e.g., nested generics) cause silent skipping or incomplete output; uncaught logic bugs in codegen lead to

🛠️How to make changes

Add support for a new target language

  1. Create a new language module in the core crate with a struct implementing the code generator trait. (core/src/language.rs (conceptual; extend with new variant))
  2. Register the new language in the writer dispatcher to route AST to your generator. (cli/src/writer.rs)
  3. Add language-specific configuration keys to the TOML schema. (cli/src/config.rs)
  4. Create golden test cases in core/data/tests/ with input.rs and output.<lang> files for each test scenario. (core/data/tests/can_generate_algebraic_enum/output.<lang>)

Add a new type constraint or validation rule

  1. Define the constraint variant in the core AST type representation. (core/src/lib.rs (or constraint module))
  2. Extend the Rust parser to recognize and extract the constraint from source. (cli/src/parse.rs)
  3. Implement constraint checking in each language backend. (cli/src/writer.rs and language-specific modules)
  4. Add test case with input.rs demonstrating the constraint and expected outputs per language. (core/data/tests/constraints_config.toml)

Add a new attribute decorator (e.g., #[serde_rename])

  1. Define the decorator struct and parsing logic in the annotation proc-macro. (annotation/src/lib.rs)
  2. Update the AST parser to extract and attach decorator metadata to types. (cli/src/parse.rs)
  3. Modify each language backend to respect the decorator during code generation. (cli/src/writer.rs)
  4. Create test cases with decorator usage and verify output in each language. (core/data/tests/decorators_config.toml and related test directories)

🔧Why these technologies

  • Rust + syn/quote crate for parsing — syn provides a robust, battle-tested Rust AST parser; quote enables compile-time code generation for proc-macros and safe string interpolation for output.
  • Proc-macro annotations (#[typeshare]) — Provides a declarative, zero-runtime-overhead API for marking types; integrates natively with Rust tooling and IDE support.
  • TOML configuration — Human-readable, widely-understood configuration format; allows per-language customization of naming, constraints, and output paths without code changes.
  • Workspace structure (annotation, cli, core, lib) — Separates concerns: proc-macro library, CLI binary, shared core logic, and public API; enables independent versioning and reuse of components.

⚖️Trade-offs already made

  • Annotation-driven over intrusive AST walking

    • Why: Developers explicitly mark types for export, preventing accidental leakage of internal types.
    • Consequence: Requires developers to opt-in via #[typeshare] annotation; slightly more boilerplate but stronger encapsulation.
  • Generate per-language files sequentially

    • Why: Simplicity in implementation; easier to debug and understand generation flow.
    • Consequence: Multi-language generation is not parallelized; slower for projects with many target languages, but typical CLI usage is fast enough.
  • Golden test fixtures (input + multi-language output files)

    • Why: Comprehensive snapshot validation; catches subtle codegen bugs and language-specific issues.
    • Consequence: High maintenance burden when changing codegen; test directories grow large; excellent confidence in correctness.

🚫Non-goals (don't propose these)

  • Runtime serialization/deserialization (only type definition export)
  • Support for non-FFI scenarios (e.g., gRPC, REST automatic client generation)
  • Bidirectional code generation (only Rust → other languages, not reverse)
  • Language interop beyond type definitions (no RPC or messaging layer)
  • IDE plugins or inline editing; purely a CLI tool

🪤Traps & gotchas

Procedural macro versions: annotation/rust-toolchain.toml and cli/rust-toolchain.toml must match or parsing will fail with cryptic errors. Config namespacing: lang-specific config in cli/data/tests/*_config.toml must use exact casing (go_config.toml, swift_prefix_config.toml)—typos silently ignore sections. Test golden files: core/data/tests/ expects input.rs to be valid Rust and output.{lang} to be byte-for-byte match (whitespace matters)—if you update a writer, all affected golden files must be regenerated. Type limitations: The parser only handles types it explicitly knows about—custom procedural macros in user code may fail silently. CI dependency: audit.yml and release.yml rely on GitHub Actions secrets (CARGO_REGISTRY_TOKEN implied)—forks won't publish without setup.

🏗️Architecture

  • mozilla/uniffi-rs — Alternative Rust FFI code generator that handles bidirectional serialization/deserialization; complements typeshare for projects needing call-through semantics rather than just type sharing
  • tauri-apps/tauri — Desktop framework that uses similar Rust-to-TypeScript type synchronization patterns for IPC, illustrates production use of FFI type sharing
  • serde-rs/serde — Serialization framework that many typeshare users pair with to serialize generated types across language boundaries
  • capnproto/capnproto — Competitor that solves polyglot type sharing via a schema language rather than Rust-first code gen; useful to understand tradeoffs
  • 1Password/typeshare-swift — Official companion package providing Swift runtime support (decoding/encoding) for types generated by typeshare

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for CLI config file parsing

The cli/data/tests directory contains multiple config files (constraints_config.toml, decorators_config.toml, etc.) but there's no evidence of corresponding test cases validating that cli/src/config.rs correctly parses each configuration variant. This is critical since config parsing is a core CLI responsibility and misconfigurations could silently fail.

  • [ ] Examine cli/src/config.rs to understand the Config struct and parsing logic
  • [ ] Create a test module in cli/src/config.rs with test cases for each .toml file in cli/data/tests/
  • [ ] Add assertions validating that each config file parses correctly and produces expected field values
  • [ ] Test edge cases like missing optional fields, invalid values, and malformed TOML
  • [ ] Run tests with cargo test --package cli to verify

Add end-to-end snapshot tests for each language output generator

The core/data/tests directory has well-organized test cases (can_generate_algebraic_enum, anonymous_struct_with_rename, etc.) with input.rs and output files for multiple languages (swift, go, kt, py, scala, ts), but there's no evidence of automated tests validating these outputs. This is a prime opportunity for snapshot/golden file testing to catch regressions.

  • [ ] Review core/src/ to locate the language-specific code generators (likely separate modules per language)
  • [ ] Create a test harness in core/src/lib.rs or a dedicated tests/ directory that reads each input.rs file
  • [ ] For each language generator, compare actual output against the corresponding output.* file using a snapshot testing crate (e.g., insta or similar)
  • [ ] Ensure all existing test cases in core/data/tests/ are covered by at least one language output
  • [ ] Run with cargo test --package core and document how to update snapshots

Extract and document language-specific code generator modules

The file structure shows tests for multiple language outputs (Swift, Go, Kotlin, Python, Scala, TypeScript) but the corresponding generator code structure is unclear. Large monolithic generator files are difficult to maintain. Refactoring should expose clear module boundaries with documented responsibilities.

  • [ ] Audit core/src/ to identify where Rust type parsing is converted to each target language
  • [ ] Create a clear module hierarchy: core/src/generators/swift.rs, core/src/generators/go.rs, etc., if not already present
  • [ ] Move language-specific formatting rules, type mappings, and keyword handling into their respective modules
  • [ ] Add module-level documentation comments explaining the generation pipeline for each language
  • [ ] Update core/README.md with a diagram or explanation of the generator architecture
  • [ ] Run cargo test to ensure refactoring doesn't break existing tests

🌿Good first issues

  • idea: Add TypeScript interface documentation comments: core/data/tests/ has examples for other languages (Swift doc comments, Kotlin kdoc) but typescript output lacks documentation generation—add docstring support to core/src/writers/typescript.rs and a test case in core/data/tests/typescript_docs/
  • idea: Extend Python constraint validation: cli/data/tests/constraints_config.toml exists but Python output doesn't leverage it for runtime assertions—add Pydantic or typing.Annotated support to core/src/writers/python.rs
  • idea: Missing Scala generic type support: core/data/tests/ has no test for generic structs (Vec<T>, Option<T>) in Scala—add a test case and extend core/src/writers/scala.rs to handle type parameters correctly

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 7d3189c — Merge pull request #284 from 1Password/typeshare-1.0.5 (darrell-roberts)
  • ecc5324 — update typeshare to 1.0.5 (darrell-roberts)
  • 0364ed8 — Merge pull request #281 from simoncozens/main (darrell-roberts)
  • c65b209 — Add documentation for type decorator (simoncozens)
  • 191298d — Support field type overrides in Python (simoncozens)
  • 7c8c3f4 — Merge pull request #280 from 1Password/release-v1.13.4 (darrell-roberts)
  • 389828a — update annotation version (darrell-roberts)
  • a469b47 — Prepare for v.1.13.4 (darrell-roberts)
  • cda469b — Merge pull request #279 from 1Password/update-mdbook-config (darrell-roberts)
  • 94a079d — Update book.toml (darrell-roberts)

🔒Security observations

The codebase demonstrates good security hygiene with automated audit workflows, appropriate Cargo configurations, and dual licensing. No critical vulnerabilities were detected. Main areas for improvement include: (1) ensuring regular dependency audits run on all CI/CD pipelines, (2) clarifying license compliance for generated code outputs, and (3) considering stricter compiler optimizations for release builds. The absence of hardcoded secrets, SQL/XSS injection vectors, or infrastructure misconfigurations is positive. Docker/container-related issues are not applicable as this is a Rust CLI library project.

  • Medium · Dependency Version Pinning Issues — Cargo.toml [workspace.dependencies]. The workspace dependencies (log = "0.4" and flexi_logger = "0.31") use caret constraints which allow minor version updates. While this enables security patches, it could introduce breaking changes or undiscovered vulnerabilities in minor versions without explicit review. Fix: Consider using exact versions (e.g., "0.4.22") for critical dependencies in production builds, or implement automated dependency audit scanning in CI/CD pipeline as already evidenced by audit.yml workflow.
  • Low · Incomplete Cargo.lock in Repository — Cargo.lock and .github/workflows/audit.yml. While Cargo.lock is present (good for reproducible builds), there's no evidence of automated dependency vulnerability scanning beyond the audit.yml workflow. Third-party dependencies could introduce transitive vulnerabilities. Fix: Ensure the audit.yml workflow runs on every pull request and commit to catch new CVEs. Consider adding cargo audit checks to the release.yml workflow as well.
  • Low · Compiler Optimizations Trade-off — Cargo.toml [profile.release]. The release profile uses opt-level = 2 (instead of 3) and thin LTO. While this improves compile times, it may reduce security-relevant optimizations for buffer overflow protections in release builds. Fix: Evaluate using opt-level = 3 with full LTO for security-critical components, though current settings are reasonable for a CLI tool. Add explicit -C overflow-checks=on if safety is critical.
  • Low · Dual License Without License File Clarification — LICENSE-APACHE, LICENSE-MIT, and README.md. The project includes both LICENSE-APACHE and LICENSE-MIT files. While this is standard practice, there's no clear indication in documentation which license applies to dependencies and generated code, which could cause compliance issues. Fix: Add a LICENSING.md file that clarifies which license covers what components and how dependencies are licensed, especially for code generation outputs.

LLM-derived; treat as a starting point, not a security audit.

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/1Password/typeshare shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live 1Password/typeshare repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/1Password/typeshare.

What it runs against: a local clone of 1Password/typeshare — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in 1Password/typeshare | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 31 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>1Password/typeshare</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of 1Password/typeshare. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/1Password/typeshare.git
#   cd typeshare
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of 1Password/typeshare and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "1Password/typeshare(\\.git)?\\b" \\
  && ok "origin remote is 1Password/typeshare" \\
  || miss "origin remote is not 1Password/typeshare (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "cli/src/main.rs" \\
  && ok "cli/src/main.rs" \\
  || miss "missing critical file: cli/src/main.rs"
test -f "core/Cargo.toml" \\
  && ok "core/Cargo.toml" \\
  || miss "missing critical file: core/Cargo.toml"
test -f "annotation/src/lib.rs" \\
  && ok "annotation/src/lib.rs" \\
  || miss "missing critical file: annotation/src/lib.rs"
test -f "cli/src/config.rs" \\
  && ok "cli/src/config.rs" \\
  || miss "missing critical file: cli/src/config.rs"
test -f "cli/src/writer.rs" \\
  && ok "cli/src/writer.rs" \\
  || miss "missing critical file: cli/src/writer.rs"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 31 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/1Password/typeshare"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Embed this chat in your README →

Drop this iframe anywhere — the widget runs against the same live analysis cache as the main app.

<iframe
  src="https://repopilot.app/embed/1password/typeshare"
  width="100%" height="500"
  style="border:1px solid #d0d7de; border-radius:8px;"
  allow="microphone"
  loading="lazy"
></iframe>