---
title: Quick Start
description: Create a container, register services, and resolve dependencies
---

## Installation

```bash
go get github.com/xraph/vessel
```

## Minimal Setup

```go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/xraph/vessel"
)

type Database struct {
    DSN string
}

func (d *Database) Name() string              { return "database" }
func (d *Database) Start(ctx context.Context) error { fmt.Println("DB connected"); return nil }
func (d *Database) Stop(ctx context.Context) error  { fmt.Println("DB disconnected"); return nil }

type UserService struct {
    db *Database
}

func main() {
    c := vessel.New()

    // Register constructors -- dependencies resolved by Go type
    vessel.Provide(c, func() *Database {
        return &Database{DSN: "postgres://localhost:5432/app"}
    })

    vessel.Provide(c, func(db *Database) *UserService {
        return &UserService{db: db}
    })

    // Resolve by type
    userService, err := vessel.Inject[*UserService](c)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("UserService uses DB at %s\n", userService.db.DSN)

    // Start all services (respects dependency order)
    ctx := context.Background()
    if err := c.Start(ctx); err != nil {
        log.Fatal(err)
    }
    defer c.Stop(ctx)
}
```

## Why This Pattern

- Dependencies are resolved by Go type, not string keys.
- Constructors are plain functions -- easy to test and reason about.
- Registration stays close to actual object construction.
- Refactors are safer because types are checked at compile time.
- The container starts and stops services in topological order.

## Alternative: Named Registration

When you need explicit names (for multiple instances of the same type, or compatibility with existing code), use `ProvideNamed`:

```go
c := vessel.New()

vessel.ProvideNamed(c, "database", func() (*Database, error) {
    return &Database{DSN: "postgres://localhost:5432/app"}, nil
}, vessel.AsSingleton())

db, err := vessel.InjectNamed[*Database](c, "database")
```

You can also register a pre-built value:

```go
cfg := &AppConfig{Port: 8080}
vessel.ProvideValue(c, cfg, vessel.WithName("config"))

config, err := vessel.InjectNamed[*AppConfig](c, "config")
```

## Next Steps

- [Constructors](/docs/forge/vessel/constructors) -- `In`/`Out` structs, named instances, groups
- [Lifetimes and Scopes](/docs/forge/vessel/lifetimes-scopes) -- singleton, transient, scoped
- [Forge Integration](/docs/forge/vessel/forge-integration) -- using Vessel inside a Forge application
