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

Llms Generator Laravel Package

ravenna/llms-generator

A Laravel/PHP package that generates llms.txt and llms-full.txt files for your project, giving AI assistants and LLM crawlers a clean, structured map of your documentation and routes so they can understand and navigate your app with less guesswork.

View on GitHub
Deep Wiki
Context7

Getting Started

This package generates llms.txt (and optionally llms-full.txt) files — the emerging Markdown convention that tells LLMs what your site is about and where to find canonical docs. In a Laravel app it's the equivalent of robots.txt for AI crawlers.

Minimal steps:

  1. composer require ravenna/llms-generator
  2. Publish config and any stub views: php artisan vendor:publish --tag=llms-generator (check php artisan vendor:publish output — the tag name may differ).
  3. Look first at the published config/llms-generator.php. This is where sources, sections, and output path are defined. Everything else hinges on this file.
  4. Run the generator command (likely php artisan llms:generate — verify with php artisan list | grep -i llms) and inspect the produced public/llms.txt.

Your first real use case: point it at your marketing pages and docs, generate the file, commit it, and serve it statically. Do not wire it into a route or live endpoint on day one — get a static file you can eyeball first. Once you trust the output, automate it.

Where to look next, in order: the config file → the generator command class (vendor/ravenna/llms-generator/src/Commands) → the output template/stub → the README's "customization" section. Because the package has 0 stars and 0 dependents, treat the source as the documentation.

Implementation Patterns

Static-file-first workflow. Generate llms.txt in CI or a deploy hook and serve it from public/. This avoids a runtime dependency and means a crawler hitting /llms.txt never touches PHP:

// config/llms-generator.php (typical shape — confirm keys against source)
return [
    'output' => public_path('llms.txt'),
    'sections' => [
        'Docs'   => ['/docs', '/guides'],
        'Blog'   => ['/blog'],
    ],
    'exclude' => ['/admin', '/login'],
];
// App\Console\Kernel or routes/console.php
Schedule::command('llms:generate')->daily();

Route-based generation for dynamic sites. If content changes per request (multi-tenant, per-locale), serve it through a controller instead, cached:

Route::get('/llms.txt', fn () => response(
    cache()->remember('llms.txt', now()->addHour(), fn () =>
        app(\Ravenna\LLMsGenerator\Generator::class)->render()
    )
));->header('Content-Type', 'text/plain');

Keep the cache TTL tied to your content publishing cadence, not arbitrarily short.

Compose from multiple sources. In practice you'll want sections pulled from: static route lists, Eloquent models (published posts, docs pages), and hand-written intro/description blocks. Treat the config as a list of "providers" and append rather than replace. If the package doesn't ship a provider abstraction, wrap its generator in your own service and post-process the string — that's a legitimate extension point and much less brittle than forking.

Multi-environment. Only generate/serve in production (and staging for staging crawl testing). In local, generate on demand:

if (app()->environment('production', 'staging')) {
    Artisan::command('llms:generate', fn () => $this->call(\Ravenna\LLMsGenerator\Commands\Generate::class));
}

Better: gate the scheduled job on environment and keep the command available everywhere.

CI integration. Add a php artisan llms:generate step to your pipeline and fail the build if git diff --exit-code public/llms.txt shows changes. This keeps the file honest and turns "someone forgot to regenerate" into a merge-blocking signal.

Gotchas and Tips

Version pin hard. 0 stars, 0 dependents, and a 0.49 score means this is essentially unvetted code you're now trusting near your public surface. Pin an exact version ("ravenna/llms-generator": "0.x.y") and review the diff on every bump. Do not use ^ ranges here.

The llms.txt spec is not stable. The convention is a proposal, not an RFC. Expect the format to evolve; treat your generated output as a template you control, not something the package guarantees. Sanity-check the output against the current spec (H1 title, blockquote summary, ## sections, Markdown link lists) before shipping — don't assume the package keeps up.

Config key drift. With low-star packages, README examples routinely lag the code. Before trusting any config snippet (including ones in this review), open vendor/ravenna/llms-generator/config/llms-generator.php and diff it against what you've written. Silent no-ops on typo'd keys are the most common failure.

Output path collisions. If output defaults to a path you don't expect, you'll "generate successfully" and find no file where you serve from. Always log or dd() the resolved output path on first run.

Serving .txt correctly. Laravel will happily serve static .txt from public/, but if you go the route/controller route, set Content-Type: text/plain; charset=utf-8 explicitly. Some proxies mangle .txt mime types otherwise.

Exclusion is a security boundary. Whatever exclude mechanism exists must cover admin routes, auth callbacks, API endpoints, and anything behind a feature flag. A generated llms.txt that advertises /admin is an invitation. Grep your generated file for /login, /password, /api/ before committing.

Debugging empty sections. If sections render blank, isolate whether the source yields zero items or the template drops them. Dump the intermediate array from the generator before rendering. This tells you whether the bug is in your config or in the package — and with no community to ask, that distinction is everything.

Extension points to prefer. In order: (1) config, (2) custom stub/template if the package uses one, (3) a thin wrapper service that post-processes the generated string, (4) a fork. Stop before step 4 unless you're prepared to maintain it — this package is small enough to fork if needed, but doing so adds a permanent tax for what is ultimately a static file.

Watch for the abandonment signal. No stars, no dependents, no recent activity means you're the maintainer now. Budget a few hours to read src/ end-to-end before you rely on it in a production deploy. If it's more than ~500 lines, that's a red flag for something this simple and worth questioning the dependency entirely — generating a Markdown file from a list of URLs is a weekend project you could own outright.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle