Weave Code
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

Project Root Laravel Package

konsulting/project-root

Resolve the correct root path when developing a Composer package or using it as a dependency. Project Root lets you target a package name and resolve paths relative to the host project, avoiding repeated “dirty” path-detection logic.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Modular Architecture: Enables clean separation between package and project roots, critical for reusable Laravel packages (e.g., plugins, service providers, or CLI tools). Reduces coupling between core app logic and dependency paths.
  • Developer Experience: Eliminates "works on my machine" issues caused by inconsistent path resolution across environments (local, CI, production). Standardizes how dependencies reference project assets.
  • Roadmap Prioritization: Justifies investment in package-based features (e.g., Laravel plugins, microservices) by providing a robust foundation for path-aware operations. Aligns with trends like composable Laravel and dependency-driven development.
  • Technical Debt Reduction: Replaces ad-hoc path logic (e.g., dirname(__DIR__, 4)) with a maintainable, tested solution, saving future debugging time.
  • Use Cases in Laravel Ecosystem:
    • Artisan Commands: Resolve project roots for commands shipped as packages (e.g., php artisan my-package:generate).
    • Service Providers: Dynamically load project-specific configs (e.g., .env overrides) from vendored packages.
    • Asset Pipelines: Locate project assets (e.g., public/) when a package handles compilation (e.g., Tailwind, Vite).
    • Testing: Isolate test environments by resolving the project root, not the package root (e.g., tests/Feature in the host project).
    • Database Migrations: Run migrations from a package that need to reference the project’s database/ directory.

When to Consider This Package

  • Adopt When:

    • Your Laravel project distributes functionality as Composer packages (e.g., plugins, libraries, or microservices).
    • You’re building CLI tools, Artisan commands, or service providers that need to reference the host project’s directories (not their own).
    • Your team struggles with fragile path resolution (e.g., hardcoded ../../../, regex-based parsing, or getcwd() hacks).
    • You prioritize long-term maintainability over short-term simplicity (e.g., avoiding custom path logic that breaks when project structure changes).
    • The package is used in multiple Laravel projects (amortizes the dependency cost and reduces duplication).
  • Look Elsewhere If:

    • Your use case is trivial (e.g., single-project CLI tools with static paths or no Composer dependencies).
    • You need advanced path resolution (e.g., multi-root projects, symlinked dependencies with custom layouts, or cross-repo monorepos). This package is simple, not comprehensive.
    • Your team lacks PHP/Composer familiarity (low adoption barrier, but requires basic setup).
    • You’re constrained by dependency bloat (this package adds ~1MB to vendor/ and has no active maintenance).
    • You’re using Laravel 10+ with native package discovery (e.g., laravel/package-discovery), which may obviate the need for manual root resolution in some cases.

How to Pitch It (Stakeholders)

For Executives: *"Imagine our Laravel packages—like the new [Plugin Name] or [Microservice]—rely on hardcoded paths to reference the host project’s files. For example, if [Plugin Name] needs to read the project’s .env or generate assets in public/, it’s currently using fragile logic like dirname(__DIR__, 3). This breaks when:

  • The project structure changes (e.g., moved from /app to /src).
  • The package is installed via GitHub repo (not Composer).
  • CI/CD environments have non-standard layouts.

This package, ProjectRoot, solves that with a single line of code: \Konsulting\ProjectRoot::forPackage('my-package')->resolve(__DIR__). It’s:

  • Reliable: Uses Composer’s autoloader to always resolve the correct project root.
  • Lightweight: Adds ~1MB to vendor/ with zero runtime overhead.
  • Future-proof: Works with Laravel 8–11 and standalone PHP projects.

Impact:

  • Fewer bugs: Eliminates path-related issues in production.
  • Faster development: No more debugging E_USER_WARNING for missing directories.
  • Reusable components: Enables safer package-based features (e.g., plugins, CLI tools).

Ask: Should we adopt this for [specific initiative, e.g., the new Plugin System]? The cost is negligible; the payoff is immediate."*


For Engineers: *"Right now, every Laravel package that needs to reference the host project’s directories is reinventing the wheel for path resolution. Here’s what that looks like today:

// ❌ Fragile (breaks if project structure changes)
$projectRoot = dirname(__DIR__, 4) . '/project-root';

// ❌ Undocumented (works on my machine)
$projectRoot = getcwd();

// ❌ Hardcoded (fragile)
$projectRoot = base_path('vendor/my-package/../../..');

ProjectRoot fixes this with:

// ✅ Clean, reliable, and self-documenting
$projectRoot = \Konsulting\ProjectRoot::forPackage('my-package')->resolve(__DIR__);

Why This Matters

  1. For Packages:

    • Resolve the project’s storage/, public/, or config/ from within a vendored package.
    • Example: A CLI tool that needs to read the project’s .env or write to storage/logs/.
  2. For Laravel:

    • Works alongside base_path(), storage_path(), etc., but for dependency-aware paths.
    • Example: A service provider that loads project-specific configs from config/packages/my-package.php.
  3. For Teams:

    • No more path-related bugs in CI or production.
    • Consistent behavior across local, Docker, and server environments.
    • Easier onboarding: New devs won’t waste time debugging dirname() hacks.

Proposal

Let’s adopt this for:

  • [Plugin Name]: Replace custom path logic in the CLI commands.
  • [Microservice]: Fix issues where the package can’t resolve the project’s database/ directory.
  • New Packages: Mandate ProjectRoot for any package needing project-relative paths.

Next Steps:

  1. Add to composer.json:
    "require": {
        "konsulting/project-root": "^1.0"
    }
    
  2. Replace one critical path in a package (e.g., logs directory) and verify it works in CI.
  3. Document the pattern in our package guidelines.

Risk: Minimal. The package is simple, tested, and used by [X] other projects. If we hit edge cases (e.g., symlinked vendors), we can extend it or fall back to __DIR__."*


For Technical Leads: *"### Architectural Fit This package aligns with Laravel’s modular design by providing a standardized way for dependencies to resolve the host project’s root. Key benefits:

  • Composer-Aware: Uses PHP’s autoloader to infer package roots, avoiding getcwd() or regex hacks.
  • Laravel-Compatible: Works alongside base_path(), app_path(), etc., but for dependency contexts.
  • Low Overhead: No performance impact (path resolution is O(1) via Composer).

Migration Strategy

  1. Audit: Find all instances of:
    • dirname(__DIR__, N)
    • getcwd()
    • Hardcoded paths like base_path('vendor/...')
  2. Pilot: Replace path logic in one package (e.g., the auth plugin) and test in CI.
  3. Rollout: Enforce ProjectRoot for new packages; phase out old logic in legacy code.

Edge Cases to Test

  • Symlinked Vendors: Does realpath() normalize paths correctly?
  • Multi-Level Dependencies: Can it resolve roots for vendor/a/b/c?
  • Windows Paths: Are separators handled (e.g., C:\project\vendor)?
  • Laravel Optimized: Does it work post-composer dump-autoload --optimize?

Alternatives Considered

Alternative Pros Cons
Custom path logic No dependencies Fragile, untested, duplicated effort.
Laravel’s Path facade Native integration Not designed for dependency contexts.
getcwd() Simple Unreliable in CLI/dependency contexts.
ProjectRoot Reliable, tested, reusable Minimal maintenance risk.

Recommendation: Adopt ProjectRoot for dependency-aware path resolution. It’s the safest, most maintainable solution for our package-heavy architecture."*

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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity