usesorane/lemme
Lemme is a lightweight Laravel package by usesorane that adds a clean, expressive helper layer to your PHP projects. Install it with Composer, keep configuration minimal, and enjoy sensible defaults that fit naturally into existing Laravel apps.
Read the source before the README. The supplied description.md describes a generic "fluent, chainable API" wrapper — boilerplate that does not match the repository description ("Generate a beautiful, fast, searchable documentation site from Markdown inside your Laravel app"). Treat the repo description and the actual src/ tree as authoritative. Start with:
composer.json — the require block gives you the real PHP/Laravel support matrix.src/ — the service provider tells you what gets registered (routes, views, commands, bindings).config/ — every knob the package exposes.README.md and any docs/ folder — for the actual method/API names.Install and pin. Because this is a 3-star, single-maintainer package at its first stable release, do not float the constraint:
composer require usesorane/lemme:"1.0.*"
composer show usesorane/lemme # record version + requires
Auto-discovery registers the provider; no config/app.php edit should be needed. Confirm by grepping bootstrap/cache/packages.php after install.
Publish the config (and views, if offered).
php artisan vendor:publish --provider="Sorane\Lemme\LemmeServiceProvider"
Use the tag form if the provider exposes one — check src/*ServiceProvider.php for publishes() calls. Published config lands in config/lemme.php; that file is now your code and must be reviewed in PRs like any other.
First use case. Point the package at a docs/ directory of Markdown files already in your repo and expose it at /docs behind your existing auth middleware. That is the lowest-risk, highest-value entry point: it gives your team an internal API/runbook site with zero new infrastructure, no database, and no queue involvement. Verify the happy path in a fresh skeleton at your target Laravel version before touching the real app.
Confine the dependency to one route group. Even if the package auto-registers routes, wrap exposure in your own configuration so you can change the prefix, middleware, or swap the renderer later without a repo-wide search:
// config/lemme.php — verify key names against the published file
'route' => [
'enabled' => true,
'prefix' => 'docs',
'middleware' => ['web', 'auth'],
],
If the package hard-registers a public /docs route with no middleware hook, that is a finding — mitigate by overriding the provider binding or by disabling package routes and registering your own controller that calls the package's renderer.
Content layout convention. Keep Markdown in a predictable tree and drive navigation from it rather than from a hand-maintained menu:
docs/
01-getting-started.md
02-api/
users.md
webhooks.md
Ordering is usually a config value, front matter, or filename prefix — check which the package supports and pick one, then enforce it in a CONTRIBUTING note. Consistency here matters more than which mechanism you choose.
Rebuild the search index on deploy, not on request. Searchable docs typically mean an index built from the Markdown. Building it per-request is the classic performance trap. Look for an artisan command (e.g. lemme:index / lemme:build) and wire it into your deploy script after config:cache, with the output cached to a path that survives releases or is regenerated each deploy.
Cache rendered HTML for stable pages. If the renderer parses Markdown on every request, wrap the page resolution in Cache::remember() keyed on file path + mtime (or on the deploy SHA). This is the single easiest win and keeps you safe if the package does no caching itself.
Override views via publishing, not by editing vendor/. Publish the Blade layout, restyle it with your app's CSS, and keep the diff small and documented. Treat published views as forked code that needs reconciliation on every upstream bump.
Test the route, not the internals. A feature test that asserts /docs/getting-started returns 200 and contains an expected heading gives you a canary for upgrades without coupling tests to the package's classes:
it('serves the docs index', function () {
$this->actingAs($this->user)
->get('/docs')
->assertOk()
->assertSee('Getting Started');
});
Keep an adapter seam for the renderer. If more than one place in the app needs Markdown-to-HTML (e.g. release notes, changelog pages), route it through a single small service of your own that delegates to the package. That gives you a one-file swap if you later move to CommonMark, a static-site generator, or an external docs host.
Versioned docs, if supported. For an internal API reference, docs/v1/, docs/v2/ with a config-driven version switch is worth the setup early — retrofitting it later means rewriting every internal link.
description.md advertises a generic fluent API; the repo describes a Markdown docs generator. Assume the marketing copy is wrong and read src/. Do not build an integration on the strength of the description alone.1.0.*, commit composer.lock, and require a green CI run before any bump. Do not trust semver from a package with this little history.config:cache will bite you. If your published config/lemme.php calls env() at the top level — or if the package's own defaults do — the value is frozen the first time you cache config. A .env change that "does nothing" is almost always this. Rebuild config as part of deploy, and prefer config-file literals over env() inside the published file.if (config(...)) around route registration) can produce routes that vanish under php artisan route:cache. Test route:cache explicitly in the spike, not just route:list on a dev machine.{{ }}, @if, or @include a technical writer puts in a code sample gets compiled. Use @verbatim, or configure the package to output pre-rendered HTML. This is the most common "my docs page is blank / broken" bug in this class of package./docs/{slug} maps to a filesystem path, verify the package normalizes and rejects ../. Test with ..%2f..%2f.env before you ship. If it does not guard, add a route constraint or a whitelist middleware in front of it.resources/views/vendor/lemme, upstream layout fixes never reach you. Note the pinned version next to the published files so the next maintainer knows what to diff against.How can I help you explore Laravel packages today?