friendsofcat/laravel-couchbase
Laravel Couchbase integrates Couchbase into Laravel with a query builder, Eloquent-style models, and cache/session drivers, making it easy to use Couchbase as a fast NoSQL backend for documents, caching, and scalable Laravel applications.
Prerequisites. This package wraps the Couchbase PHP SDK, which is a native extension (ext-couchbase), not just a Composer dependency. Confirm php -m | grep couchbase before you start — if it's missing, install it with pecl install couchbase (or from the Couchbase SDK tarball). You also need Couchbase Server 7.x+ to use scopes/collections, which the package assumes.
Install and wire up.
composer require friendsofcat/laravel-couchbase
php artisan vendor:publish --tag=couchbase-config # verify actual tag in the README
The service provider is auto-discovered. Populate .env with the values the config file reads:
COUCHBASE_HOSTS=127.0.0.1
COUCHBASE_USERNAME=Administrator
COUCHBASE_PASSWORD=password
COUCHBASE_BUCKET=default
COUCHBASE_SCOPE=_default
COUCHBASE_COLLECTION=_default
Where to look first. Read config/couchbase.php to see every connection option (hosts, credentials, bucket/scope/collection, timeouts, SDK options). Then look at src/Model.php and the query builder under src/ — those two files define most of the day-to-day API surface. If any method name differs from what you expect, the README and the src/ directory are the source of truth; this is a small package and moves slower than Eloquent.
First use case. Create one model per collection for key-value access — the common case for Couchbase:
use Friendsofcat\Couchbase\Model;
class User extends Model
{
protected $bucket = 'default';
protected $scope = '_default';
protected $collection = 'users';
}
Then User::find($key), $user->name = 'Ada'; $user->save();, $user->delete(); work as KV operations — the fast path Couchbase is designed for. Reach for N1QL only when you actually need to query by non-key attributes.
Model-as-collection mapping. One model class per collection keeps bucket/scope/collection wiring declarative. Override $bucket, $scope, and $collection per model; put defaults in the config so simple apps never touch them. For multi-tenant or multi-environment data, add a connection per cluster in config/couchbase.php and select it on the model or call.
KV vs. N1QL — design around it. Couchbase's differentiator is sub-millisecond key lookups. Use find($id) and save() for the primary access path. Use the query builder (Model::where('status', 'active')->get()) only for secondary access patterns — and remember each pattern needs a matching secondary index. A common pattern is find() for detail pages and a small number of N1QL queries for list views.
Raw SDK access when the builder runs out. The package is thin on purpose. For N1QL features it doesn't expose (subqueries, LET, MERGE, aggregations with GROUP BY tuning, EXPLAIN), drop to the underlying cluster/collection handle via the facade or connection object and run cluster()->query(...). Keep that behind a repository class so it's testable and swappable.
Wrap in repositories. Don't let Couchbase::... calls leak into controllers. A UserRepository with find, save, listActive, and an explicit collection handle injected from the model is the cleanest way to survive the package's low release cadence — if a bug forces you to fork or swap to the raw SDK, only the repository changes.
Set up indexes with the app, not by hand. Any where/orderBy you rely on needs a GSI (Global Secondary Index). Create indexes as part of a migration/seeder step or a dedicated Artisan command so local, staging, and CI environments start with the same schema. A missing index is the most common cause of "it works in dev" bugs.
Testing pattern. There is no meaningful in-memory mock of Couchbase. Stand up a couchbase:7.x container in docker-compose.yml, point the test config at a dedicated bucket, and flush (or DELETE FROM) between tests. Write factories that set deterministic keys so assertions don't depend on generated UUIDs.
Multiple connections for read/write or regional splits. Define more than one entry under connections and select per model or per call. Useful for separating an analytics cluster from an operational one, or for a per-tenant cluster topology.
ext-couchbase fails to build on Alpine and ARM hosts more often than not. Use the official couchbase Docker image (and match its server version to production) rather than compiling against a base PHP image.ext-couchbase provides. Composer may resolve to an older major SDK than the server expects. Pin both explicitly in composer.json.hasMany/belongsTo, no eager loading, no observers, no model events by default, and partial pagination. Don't port a full Eloquent app to it — port the models that genuinely benefit from KV access and keep relational data in SQL.save(), a subsequent where query may not see the write because the GSI lags. Use the builder's scan-consistency option (request_plus or equivalent) for read-after-write paths; leave it at the default for high-throughput reads.config:cache bakes credentials. Credentials end up in the cached config — use env vars and avoid config:cache in images that are shared across environments.DB::listen() to see N1QL. Laravel's query listener hooks PDO, not this driver. Add logging in your repository layer, or use the Couchbase SDK's own logging to trace slow statements.patches/ directory with composer-patches, and write the repository abstraction above so you can drop to the raw SDK quickly.How can I help you explore Laravel packages today?