Framework
nuwave/lighthouse avatar
nuwave/lighthouse

nuwave/lighthouse: serving GraphQL from a Laravel application

A framework for serving GraphQL from Laravel

3,497 stars467 forksPHPMIT

At a glance

What is it?
Lighthouse is a GraphQL framework that plugs into Laravel and lets you define a schema in SDL while resolvers stay in PHP. This article covers the mechanism, a first install, and the limits you should weigh before adopting it.
Who is it for?
Adopt nuwave/lighthouse if your API surface is already a Laravel application and you want the schema written in SDL rather than in PHP classes. Do not adopt it if you need a framework-agnostic GraphQL server, or if you cannot accept that the repository is scheduled to move to spawnia/lighthouse.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem nuwave/lighthouse solves for Laravel teams

A Laravel application already has models, Eloquent relationships, validation, policies and a service container. Adding GraphQL usually means introducing a second set of concepts: resolver classes, type definitions in PHP, a separate schema builder, and a mapping layer between the two worlds. Lighthouse takes the position that most of that mapping is mechanical and can be generated from a schema written in the GraphQL Schema Definition Language.

The audience is narrow and specific. It is for teams whose backend is Laravel and who want the API contract expressed as SDL text, checked into the repository, and readable by frontend developers without reading PHP. The README describes the project as a GraphQL framework that integrates with your Laravel application and combines the best ideas of both ecosystems. That combination is the whole value proposition: you keep Eloquent and the container, and you gain a typed query language on top.

If your backend is Symfony, Slim or plain PHP, this is the wrong tool. The integration is with Laravel, not with PHP in general, and the parts that make it pleasant (directives that map to Eloquent, authorization through Laravel policies) depend on Laravel being present.

How Lighthouse turns a schema file into resolvers

The mechanism is directive-driven. You write types and fields in SDL and attach built-in directives to them. The framework reads the schema, and for each field it derives the resolver behaviour from the directive rather than from a hand-written class. A field marked with a directive that names an Eloquent model resolves by querying that model, and the arguments on the field become constraints on the query.

Because the schema is the source of truth, the data flow is: incoming GraphQL query, parsed and validated against the SDL, each selected field dispatched to the resolver implied by its directive, results assembled back into the response shape. Nested fields resolve through relationships the same way, so a query that walks from a user to their posts does not need a resolver per level.

The repository layout reflects this. There is a src/ directory for the framework, a tests/ directory, and a docs/ directory that holds the documentation source per major version. The README points at lighthouse-php.com for the rendered documentation and notes that you can find docs for a specific version by browsing /docs/master at the corresponding tag in the git history. That is a practical detail: the published site follows the current major version, so older behaviour has to be read from the tagged tree.

Installing nuwave/lighthouse and running a first query

The README does not carry install instructions; it points to lighthouse-php.com for the documentation. What the repository does show is how the maintainers set up the project itself, which is a useful signal about the intended environment. The Makefile defines a setup target that builds the Docker containers, installs Composer dependencies and prepares the docs. The docker-compose.yml defines a php service built from php.dockerfile, a mysql service running mysql:5.7, and a redis service running redis:6.

For a consuming application, the dependency is installed through Composer. The package name in composer.json is nuwave/lighthouse.

bash
composer require nuwave/lighthouse

Beyond that, the README does not document the publishing or configuration steps, so treat the official documentation as the authority for schema file placement and configuration keys. What can be stated from the repository is the toolchain the project expects: PHP, Composer, and for the test suite a MySQL database and Redis. If your application does not already run those services, that is part of the setup cost.

To run the project's own checks locally, the Makefile exposes named targets. These run inside the Docker containers rather than on the host.

bash
make setup
make test
make stan

make setup prepares the environment, make test runs PHPUnit through the php container, and make stan runs PHPStan. The it target chains fix, stan and test, which is the pre-commit sequence the maintainers use.

The versioning contract and what it does not cover

Lighthouse follows Semantic Versioning, and the README is unusually explicit about the boundary. Only the current major version receives new features and bugfixes. Updating between minor versions does not require changes to PHP code or to the GraphQL schema, and causes no breaking behavioural changes for consumers of the API. That is a strong promise for a framework that sits between your database and your clients.

The caveat is the important part. Only code elements marked with @api remain compatible across minor versions. Everything else in Lighthouse is internal and subject to change. So if your application reaches into framework classes rather than using the documented extension points, a minor upgrade can break you even though the schema and the API surface are untouched. The distinction between public and internal is marked in the source, not in a separate document, which means you have to check the annotations before depending on a class.

Major upgrades are a different matter. The README directs you to UPGRADE.md when moving between major versions. There is no claim that major upgrades are automatic, and no tooling is described that performs the migration for you.

Where Lighthouse is the wrong choice

The most concrete limitation is organisational rather than technical: the README states that the repository is planned to move to spawnia/lighthouse, with an announcement linked in the discussions area. Anyone adopting today should read that announcement and decide whether the move affects their dependency management, issue reporting or CI configuration. A package rename is not a code change, but it is a change to where you file bugs and where releases appear.

The second limitation is the coupling itself. Lighthouse is not a general GraphQL server with a Laravel adapter bolted on; it is built around Laravel's conventions. Teams that expect to swap the underlying framework, or that run a polyglot backend where GraphQL is one service among several, will find the directive model assumes Eloquent and the container are available. In that situation a framework-agnostic server is a better fit.

Third, the documentation lives outside the repository. The README is short and defers to lighthouse-php.com for everything practical: installation, configuration, directive reference. That means offline reading of the docs requires checking out the tagged tree under docs/. It also means the README alone is not enough to evaluate the project.

How this differs from a schema-first PHP GraphQL server

The natural alternative is a standalone GraphQL implementation for PHP that is not tied to a framework. The difference in approach is where the resolver logic lives. In a standalone server you register types and resolvers programmatically, and the framework you happen to use is invisible to the GraphQL layer. You write more wiring, but nothing in the GraphQL layer knows about your ORM.

Lighthouse inverts that. The schema declares intent through directives, and the framework supplies the resolution strategy, including database access through Eloquent. You write less wiring, and in exchange the GraphQL layer is aware of Laravel. For a Laravel-only backend that trade is favourable. For a backend that might migrate, or that needs the same schema served from a non-PHP service, the standalone approach keeps the option open.

A second, less obvious difference is schema ownership. With Lighthouse the SDL file is the artefact you review in pull requests, and changes to it are the changes to your API contract. With programmatic type registration, the contract is distributed across PHP classes, and reviewing a schema change means reading code. Teams that want the schema reviewable as text will prefer the SDL approach regardless of framework.

Maintenance, licensing and upgrade cost

The repository is not archived and the last push was on 2026-09-02, the same day as the v6.70.1 release. Recent releases are frequent and close together: v6.70.0 and v6.70.1 both landed on 2026-09-02, with v6.69.2 before them on 2026-07-29. That release cadence is the maintenance signal, not any counter on the repository page.

The project is MIT licensed. In practical terms that permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. This is not legal advice; if your organisation has a policy on third-party licences, the LICENSE file is the authority.

Upgrade cost splits by version boundary. Minor upgrades are covered by the README's promise that PHP code and the schema do not need changes, with the @api caveat. Major upgrades require reading UPGRADE.md and budgeting for whatever it lists. Because only the current major version gets fixes, staying on an older major means accepting that bugs found there will not be patched. That is a real cost for teams that pin versions for long periods.

Editorial conclusion

Adopt nuwave/lighthouse if your API surface is already a Laravel application and you want the schema written in SDL rather than in PHP classes. Do not adopt it if you need a framework-agnostic GraphQL server, or if you cannot accept that the repository is scheduled to move to spawnia/lighthouse. Verify first which major version you are installing and read UPGRADE.md before any major bump.

Frequently asked questions

What is nuwave/lighthouse used for?

It is a framework for serving GraphQL from Laravel. It integrates with your Laravel application and lets you define the GraphQL schema while keeping Laravel's models and container available to the resolvers.

How do I install nuwave/lighthouse?

The README does not include install steps and points to lighthouse-php.com for the documentation. The package name in composer.json is nuwave/lighthouse, so the dependency is added through Composer.

Does nuwave/lighthouse receive updates?

The repository is not archived and the last push was on 2026-09-02, matching the v6.70.1 release. Only the current major version receives new features and bugfixes.

What licence does nuwave/lighthouse use?

The repository lists the MIT licence, and the LICENSE file is included at the top level.

How do I run the nuwave/lighthouse test suite?

The Makefile defines a test target that runs PHPUnit inside the php Docker container, and a stan target that runs PHPStan the same way. The docker-compose.yml defines the php, mysql and redis services those targets depend on.

Official sources

  1. License: MIT
  2. nuwave/lighthouse on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nuwave-lighthouse.svg)](https://hysenlabs.com/projects/nuwave-lighthouse)