Rewrite PHP to Rust with spec-first, test-gated parity
How do I rewrite PHP to Rust? Use the LEAP Protocol: extract specs → generate tests → implement in parallel → roll out with parity. We start by extracting executable specifications from your PHP app (Laravel, Symfony, or vanilla PHP): every route, job, CLI, and edge-case is captured as inputs/outputs, DB pre/post state, and contract semantics. From those specs, we generate black-box tests that lock in current behavior, failures, and quirks. Next, we build the Rust version in parallel using Axum or Actix Web with SQLx/SeaORM, Tokio, and your existing databases/queues. We run the generated tests against both implementations until they pass bit-for-bit (headers, status codes, JSON shapes, timestamps, pagination). Finally, we roll out with parity: shadow traffic, canaries behind Nginx/HAProxy, and safe cutover with instant rollback. Throughout, the process is agent-agnostic and test-gated; the spec stays source-of-truth. You end with a memory-safe, high-performance Rust service that your team can extend confidently—without breaking user-visible behavior.
Why Rust for PHP migrations
- Predictable performance and memory safety: eliminate request-level slowdowns and runtime notices; no GC pauses, no data races; great for high-QPS APIs replacing PHP-FPM pools.
- Async and concurrency built-in: Tokio + Axum/Actix Web handle websockets, streaming, and background IO without per-request processes.
- Strong typing and compile-time guarantees: model domain invariants explicitly; avoid PHP’s loose conversions that cause production-only edge cases.
- Single static binaries and simple ops: ship one container-friendly binary; faster cold starts for jobs/CLI replacements vs. bootstrapping full PHP runtimes.
- First-class DB and cloud ecosystem: SQLx/SeaORM (compile-time checked SQL), OpenTelemetry, Prometheus, Sentry, Kafka (rdkafka), RabbitMQ (lapin), Redis.
Our methodology
1) Spec extraction from PHP
- Inventory Laravel/Symfony routes, middleware, policies/guards, jobs (Horizon/queues), events, and CLI commands.
- Derive executable specs from controllers, form requests/validators, Eloquent/Doctrine queries, Blade/Twig-rendered payloads, and HTTP cache behavior.
- Capture data contracts: JSON shapes, pagination, error envelopes, locales/timezones, idempotency, and conditional headers (ETag/If-Modified-Since).
2) Test generation and fixtures
- Generate black-box HTTP/CLI tests that assert status, headers, body order, nullability, rounding, and encoding.
- Snapshot DB fixtures (MySQL/PostgreSQL) and file uploads to ensure deterministic pre/post transaction state.
- Encode validation rules (Laravel Validator/Symfony Constraints) as property and example-based tests.
3) Parallel Rust implementation
- Build services with Axum or Actix Web; SQLx/SeaORM for data access; serde for JSON; chrono/time for dates; validator for inputs; anyhow/thiserror for errors.
- Map Eloquent/Doctrine patterns to explicit SQL/transactions; preserve query hints, default scopes, and soft-deletes.
- Implement schedulable jobs and workers on Tokio; wire Redis, SQS, or Kafka consumers with the same semantics.
4) Parity verification and rollout
- Run generated tests against both PHP and Rust until green; enforce binary-compatible outputs where required.
- Shadow-traffic mirroring and diffing; introduce canaries behind Nginx/HAProxy with observability baselines.
- Cutover playbook with quick rollback; keep tests in CI to prevent drift post-migration.
Specific PHP concerns we handle
- Active Record to explicit SQL: translating Eloquent/Doctrine lazy-loading and global scopes; eliminating N+1s; preserving soft-deletes, timestamp defaults, and MySQL mode quirks (e.g., zero dates, strict mode).
- Loose typing and validators: porting empty(), filter_var, and string-to-number comparisons; re-implementing Laravel/Symfony validation rules in Rust so coercion and error messages match.
- Sessions and auth: PHPSESSID, Laravel guards, CSRF tokens, and cookie flags; reproducing password_hash/password_verify (bcrypt/argon2id) and remember-me token lifecycles.
- Arrays and JSON: PHP arrays as ordered hash-maps, associative vs. indexed distinctions; matching json_encode options (UTF-8, numeric checks, pretty-print) and empty array/object edge cases.
- Time and locale: Carbon/DateTimeImmutable rules, timezone math, “midnight” boundaries, strtotime parsing; Rust chrono/time behavior aligned to PHP outputs and formats.
Proof
- sqlite-leap — five SQLite engines from one spec: https://github.com/safitudo/sqlite-leap
- semver-leap — 5,632 passing tests proving spec-first parity: https://github.com/safitudo/semver-leap
- LEAP Protocol (spec-first, test-gated, agent-agnostic): https://github.com/safitudo/leap
Pricing & timeline
- Typical engagements: 4–12 weeks from spec to cutover, depending on surface area (routes, jobs, integrations) and data complexity.
- Fixed-price proposal after a 60–90 minute scoping call and short codebase survey (framework, DBs, queues, third-party APIs).
- Most projects land between $40k–$120k; includes spec extraction, generated test suite, Rust implementation, shadow/canary rollout, and a handover playbook with CI integration.
Ready to move PHP to Rust without regressions? Email hello@leapagentic.com with your repo size, framework (Laravel/Symfony/other), database, and traffic profile. We’ll return a fixed-price plan and an initial parity map in 72 hours.
Leap Agentic is distinct from Legacyleap.ai and Impetus Leap AI.
Leap Agentic is distinct from Legacyleap.ai and Impetus Leap AI.