ahmedtarboush / papyrus-docs
A native, reflection-based documentation generator for Laravel. Turns your code into a living codex.
Package info
github.com/ahmedaymantarboush/papyrus-docs
Language:JavaScript
pkg:composer/ahmedtarboush/papyrus-docs
Requires
- php: ^8.2
- illuminate/routing: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- illuminate/view: ^10.0|^11.0|^12.0
- phpdocumentor/reflection-docblock: ^5.3
Requires (Dev)
- orchestra/testbench: ^10.9
- pestphp/pest: ^3.8
- pestphp/pest-plugin-laravel: ^3.2
README
¶ PAPYRUS DOCS
A Postman-like API documentation & testing client — natively inside Laravel.
What is Papyrus?
Papyrus Docs is an enterprise-grade API documentation and playground that lives inside your Laravel application. It automatically reads your FormRequest validation rules — including nested arrays, Enum options, file uploads, and conditional rules — and renders them as an interactive, Postman-like testing UI with zero configuration.
No OpenAPI YAML. No manual annotations. Just write your FormRequests, and Papyrus does the rest.
Why Papyrus?
| Feature | Postman | Swagger UI | Papyrus |
|---|---|---|---|
| Zero-config from FormRequest | ❌ | ❌ | ✅ |
| Recursive nested objects/arrays | ❌ | Partial | ✅ |
| Two-Way Visual ↔ JSON sync | ❌ | ❌ | ✅ |
| Dynamic Enum / Select detection | ❌ | Manual | ✅ |
| Inline key editing & type morphing | ❌ | ❌ | ✅ |
| File upload + FormData auto-handling | ✅ | ❌ | ✅ |
| Lives inside your Laravel app | ❌ | ❌ | ✅ |
Features at a Glance
- 🧠 Exhaustive Validation Engine — Parses every Laravel 12 rule:
required,nullable,min,max,regex,between,confirmed,dimensions, conditional rules (required_if,prohibited_unless), and more. - 🔍 Dynamic Type Discovery — Rules like
uuid,ulid,ip,mac_addressare dynamically registered as custom types with format-specific UI hints. - 📋 Enum & Options Extraction — Automatically extracts
in:a,b,c,Rule::in(), and PHP 8.1+ Enum cases into selectable dropdowns. - 🔄 Two-Way Sync — Edit payload via Visual Form or Raw JSON — changes sync bidirectionally with a file-guard safety mechanism.
- ☑️ Postman Checkbox — Toggle individual fields on/off. Disabled fields are excluded from the request but preserved in state.
- ✏️ Inline Key Editor — Click any key to rename it. Add/remove custom properties dynamically.
- 🔁 Recursive Form Engine — Infinite nesting via
DynamicField→ObjectBuilder→ArrayBuilder→DynamicField. - 📝 Non-Truncated Validation Badges — All rules displayed as expandable badges, never truncated.
- 🔧 DocBlock Overrides — Absolute manual control with powerful custom directives like
@papyrus-bodyParam,@papyrus-queryParam,@papyrus-header, and multi-line markdown blocks for@papyrus-description-startand@papyrus-responseExample-start. - 📡 Code Snippets — Auto-generated cURL, PHP (Guzzle), JavaScript (fetch), and Python (requests) snippets for every endpoint.
- 📦 FormData Auto-Handling — File uploads automatically switch to
multipart/form-datawith correct boundary headers. - ⚙️ Configurable Grouping — Group endpoints by controller, route name, or URI regex patterns.
- 🎨 Global Dark & Light Mode — Fully responsive dark theme that defaults to your OS preference.
- 🎯 OpenAPI Export — Export your documentation as OpenAPI 3.0 JSON specification.
- 📮 Postman Export — Export as Postman Collection v2.1 for team sharing.
- 🛡️ Authorization Gate — Built-in
viewPapyrusDocsgate for access control. - 🐛 Debug Mode — Debug headers with execution time, memory usage, PHP and Laravel versions.
- 🔧 Artisan Commands —
papyrus:installfor one-step setup.
Installation
1. Require the package
composer require ahmedtarboush/papyrus-docs --dev
2. Run the install command (recommended)
php artisan papyrus:install
This publishes both the config file and production assets in one step.
3. Or publish manually
# Config only php artisan vendor:publish --tag=papyrus-config # Assets only (for production) php artisan vendor:publish --tag=papyrus-assets
4. Access the dashboard
Navigate to:
http://your-app.test/papyrus-docs
That's it. No annotations required. Papyrus automatically scans your routes and FormRequests.
Quick Start
Step 1: Create a FormRequest
class StoreUserRequest extends FormRequest { public function rules(): array { return [ 'name' => 'required|string|max:255', 'email' => 'required|email|unique:users', 'age' => 'nullable|integer|min:18|max:120', 'role' => ['required', Rule::in(['admin', 'editor', 'viewer'])], 'avatar' => 'nullable|image|max:5120|extensions:jpg,png,webp', 'tags' => 'array', 'tags.*' => 'string|max:50', ]; } }
Step 2: Type-hint it in your controller
/** * Register a new user. * * Creates a user account with the provided details, * profile picture, and role assignment. * * @group Users */ public function store(StoreUserRequest $request) { // ... }
Step 3: Open Papyrus
Visit /papyrus-docs in your browser. The endpoint above will appear with:
- All fields rendered with correct input types (email field, number with min/max, file upload with
.jpg,.png,.webpaccept filter) rolerendered as a Select dropdown withadmin,editor,viewertagsrendered as a repeatable array builder- Validation badges showing
required,string,max:255on each field - A fully functional playground to test the endpoint with real requests
Documentation
| Doc | Description |
|---|---|
| Configuration | Every config key explained |
| Validation Engine | How FormRequest rules become UI components |
| Custom Directives | DocBlock overrides & @papyrus-bodyParam |
| Smart UI Guide | Two-Way Sync, Postman Checkbox, Inline Editor |
Artisan Commands
papyrus:install
One-step installation that publishes both config and assets:
php artisan papyrus:install
Equivalent to running:
php artisan vendor:publish --tag=papyrus-config php artisan vendor:publish --tag=papyrus-assets
papyrus:export
Export your API schema directly to a JSON file (uses config('papyrus.export_path')):
# Export OpenAPI 3.0 (default) php artisan papyrus:export # Export Postman Collection v2.1 php artisan papyrus:export --type=postman
Exporters
OpenAPI 3.0 Export
Papyrus includes an OpenApiGenerator that converts your scanned routes into an OpenAPI 3.0 specification:
use AhmedTarboush\PapyrusDocs\Exporters\OpenApiGenerator; use AhmedTarboush\PapyrusDocs\PapyrusGenerator; $schema = app(PapyrusGenerator::class)->scan(); $openApi = (new OpenApiGenerator())->generate($schema); // Returns a complete OpenAPI 3.0 spec array with: // - info (title, version) // - paths (with tags, summary, description, requestBody, responses)
Configure the export via config/papyrus.php under the open_api key.
Postman Collection Export
The PostmanGenerator exports your API as a Postman Collection v2.1:
use AhmedTarboush\PapyrusDocs\Exporters\PostmanGenerator; use AhmedTarboush\PapyrusDocs\PapyrusGenerator; $schema = app(PapyrusGenerator::class)->scan(); $postman = (new PostmanGenerator())->generate($schema); // Returns a Postman v2.1 collection with: // - info (name, schema URL) // - item[] (grouped by API group, with name, request, body)
Import the resulting JSON directly into Postman to share with your team.
Debug Mode
Enable debug mode to get execution metadata in the schema API response headers:
PAPYRUS_DEBUG=true
The /papyrus-docs/api/schema endpoint will include:
| Header | Description |
|---|---|
X-Papyrus-Debug-Time-Ms |
Schema generation time in milliseconds |
X-Papyrus-Debug-Memory-Mb |
Memory consumed during generation |
X-Papyrus-Debug-PHP |
PHP version |
X-Papyrus-Debug-Laravel |
Laravel version |
Authorization
By default, Papyrus is only accessible in local and testing environments via the viewPapyrusDocs gate.
The default gate definition:
Gate::define('viewPapyrusDocs', function ($user = null) { return app()->environment('local', 'testing'); });
To customize access, override the gate in your AuthServiceProvider:
Gate::define('viewPapyrusDocs', function ($user = null) { return $user && $user->isAdmin(); });
Internal Routes
Papyrus registers these routes under the configured URL prefix:
| Route | Purpose |
|---|---|
GET /papyrus-docs |
The SPA UI (gated by viewPapyrusDocs) |
GET /papyrus-docs/api/schema |
JSON schema endpoint (used by the UI) |
GET /papyrus-docs/assets/{path} |
Static asset serving (JS, CSS, fonts) |
GET /papyrus-docs/favicon/{file?} |
Favicon serving |
All routes respect the middlewares config and are prefixed with the url config value.
Disabling in Production
Set the environment variable:
PAPYRUS_ENABLED=false
This prevents all Papyrus routes from being registered. The ServiceProvider short-circuits entirely.
Requirements
- PHP 8.1+
- Laravel 10, 11, or 12
phpdocumentor/reflection-docblock(auto-installed)
Created By
Ahmed Tarboush — LinkedIn
License
Papyrus Docs is open-source software licensed under the MIT License.