Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Resume Php Laravel Package

juststeveking/resume-php

juststeveking/resume-php lets you model your CV in typed PHP classes, covering basics, work history, education, skills and projects. Compose sections programmatically, then export a structured JSON resume for rendering or sharing, keeping your resume version-controlled in Laravel or plain PHP projec...

View on GitHub
Deep Wiki
Context7

Getting Started

Install and pin.

composer require juststeveking/resume-php:^1.0

Pin the exact version in composer.json and commit composer.lock. This is a single-maintainer package; a loose constraint buys you nothing and costs you reproducibility.

Verify your runtime first. Confirm the PHP constraint in the package's composer.json (expect 8.2+) before you write anything. If you're on an older runtime, that's a hard stop, not a "we'll upgrade later" — don't let a resume library drag your platform version.

Where to look, in order:

  1. README.md — the fluent builder examples are the API contract you'll actually use.
  2. src/ — find the top-level builder/factory entry point and the value objects for work, education, skills, and sections. This tells you what's typed and what's just strings.
  3. tests/ — this is the real documentation. Upstream has no golden-file rendering tests, so the test suite is your best evidence of intended composition order and optional-field handling.
  4. The 0.0.2 → 1.0.0 diff — specifically for construction API changes. The release note "major fixes and improvements to how we build resumes" means any snippet you find online predating 1.0.0 is suspect.

First use case: one resume, one output, in a throwaway command.

Don't start with your database. Start with a hardcoded resume in an Artisan command or a php -r scratch file, covering the awkward cases up front: a role with no end date (current job), a role with no location, a section with one item, and a candidate with many roles. Render it to JSON. Then render it to HTML. That's an afternoon, and it answers every question that gates your estimate — does the builder compose the way the README claims, does serialization round-trip, is the output deterministic.

// Illustrative shape — verify method names against src/ before relying on them.
$resume = Resume::make()
    ->withBasics(/* name, label, email, ... */)
    ->addWork(
        Work::make()
            ->withName('Acme')
            ->withPosition('Engineer')
            ->withStartDate('2021-03-01')
            ->withLocation(/* structured location added in 1.0.0 */)
            ->addHighlight('Shipped the thing')
    )
    // ... education, skills, projects
    ->build();

$json = json_encode($resume, JSON_PRETTY_PRINT);

Once that renders correctly, you have your baseline and you can size the real integration.

Implementation Patterns

Wrap it in one adapter, immediately. The single highest-value pattern: a ResumeComposer (or similar) service that is the only place vendor types appear. Controllers, jobs, and Blade templates talk to your interface; the adapter talks to the package. This is what makes fork-or-swap a contained task instead of a rewrite, and it's cheap on day one and expensive to retrofit.

interface ResumeComposer
{
    /** @return array<string, mixed> */ // or your own DTO
    public function compose(CandidateProfile $profile): array;
}

Return plain arrays or your own DTOs from the adapter, never vendor objects. If you persist vendor objects, a field addition upstream becomes a data migration.

Hydrate from your domain models, don't hand-build in controllers. Put the mapping from your User/Experience/Education Eloquent models into the adapter as explicit methods. Resume data has fiddly optionality — date ranges that are open-ended, education without a GPA, skills grouped by category — and you want that mapping in one reviewable file with tests, not scattered across five controllers.

final class EloquentResumeComposer implements ResumeComposer
{
    public function compose(CandidateProfile $profile): array
    {
        $builder = Resume::make()->withBasics($this->basics($profile));

        foreach ($profile->experiences()->orderByDesc('started_at')->get() as $role) {
            $builder->addWork($this->work($role));
        }

        return $builder->build()->toArray(); // verify the actual serialization method
    }
}

Render separately from compose. Compose to JSON, persist that JSON if you need drafts, and render HTML from the JSON in a distinct layer. This gives you three independent things to test: the mapping, the serialization, and the template. It also means a template change never risks a data-shape change.

Keep your Blade templates boring. Blade does the HTML; the package does not do styled rendering. Expect to write the layout yourself — semantic sections, print CSS, page-break rules. Do not expect the package to save you this work, and do not let anyone's estimate imply it will.

Gate the AI skill explicitly. 1.0.0 added an "AI skill." Before it's anywhere near a request path: confirm whether it's runtime code, whether it makes outbound network calls, whether it needs credentials. Default it off in config. If it's inert (an agent-instruction file or dev-only tooling), note that and move on — but verify rather than assume, because non-determinism in a rendering path breaks your golden files silently.

Golden-file tests over two or three resumes. Commit expected output for: a complete resume, a resume with missing location and an open-ended role, and a resume with many roles plus custom sections. Any patch bump gets diffed rather than trusted. This is the cheapest insurance available and it's not optional given there are no upstream rendering tests.

Generate on a queue, not inline. Resume composition and HTML rendering are cheap but not free, and PDF rendering (which you're adding yourself) is definitely not free. A GenerateResumePdf job keeps request latency flat and gives you a natural place to retry and log.

Custom sections are your escape hatch. If your model has non-standard blocks — publications, speaking, certifications with vendor-specific fields — model them as custom sections rather than fighting the built-in types. That keeps upgrade risk low: standard fields stay standard, bespoke fields live in one place you control.

Gotchas and Tips

1.0.0 is a different construction API from 0.0.2 — assume it until proven otherwise. The release notes say "major fixes and improvements to how we build resumes," and there is no upgrade guide, only PR titles. Do not bump in place. Branch, pin ^1.0, port your most complex resume, and diff rendered output against your 0.0.2 baseline if you have one. The result is a fork in the road: mechanical port (days) or substantive rewrite (a sprint). Report it as a range until you know.

Verify optionality of location before designing around it. 1.0.0 added structured work location, and the geo-aware features everyone wants (commute radius, relocation filters, regional benchmarks) depend on it — but only if it degrades cleanly when absent. Test a role with no location and confirm your template doesn't render null, an empty paren, or a stray separator. Most historical data won't have it, so the missing case is the common case, not the edge case.

Check round-trippability early if you plan to persist drafts. Serialize → hydrate → serialize and compare. If hydrate isn't supported or loses information, you can't store drafts as package objects, and your persistence decision is made for you: store your own JSON, hydrate at render time.

Determinism will bite your snapshot tests. Watch for timestamps, "generated on" footers, and non-stable collection ordering. Sort work entries explicitly by start date in your adapter rather than trusting input order. Any embedded current-date is a test that fails tomorrow — strip it from the snapshot or freeze the clock.

Keep vendor types out of anything serialized into a queue payload. Laravel will happily serialize an object graph into a job; six months later a patch release adds a typed constructor property and your queued jobs start failing on unserialize. Pass IDs and scalar arrays across the queue boundary.

Bus factor is one. No organisational backstop, a first-time contributor in this release. Concretely: document the fork-and-patch contingency in the repo, keep the adapter under ~200 lines so a fork is hours not days, and subscribe to the repo's releases so you see 1.1.0 before your lockfile does.

Facade and config collisions are a staging problem, not a review problem. If the package registers a facade alias or publishes a config key, check the name against your app's existing aliases before it surprises you in a deploy. Confirm rather than assume — Laravel-ecosystem conventions make auto-discovery likely, but this package is framework-agnostic by design and may deliberately not ship a service provider.

Extension points worth knowing: custom sections for non-standard blocks; your own renderer layer for output fidelity (the package gives you the data, you own the layout); and the JSON schema shape itself, which is an interchange format — if candidate records need to move between systems, serialize from this model rather than inventing a mapper per consumer.

Keep the estimate honest with stakeholders. This package models resume data. It does not parse PDFs/DOCX, it does not render styled documents, it does not score for ATS, and it does not rank candidates against a job. Those are separate workstreams and they carry most of the cost. Adopting this de-risks the data layer and nothing else — say so explicitly, or the first sprint review will be unpleasant.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route