> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uniac.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Services and Systems

> The two kinds of Uniac package.

A Uniac package is either a **Service** or a **System**. Both subclass marker classes from the `uniac` SDK and declare their dependencies as class-level type annotations.

| Kind  | SDK base class  | Purpose                                                         |
| ----- | --------------- | --------------------------------------------------------------- |
| `lib` | `uniac.Service` | Reusable building block, consumed by other Services or Systems. |
| `app` | `uniac.System`  | Deployable composition. Each deploy targets one System.         |

The `kind` field in [`uniac.json`](/concepts/manifest) selects which one applies.

## Declaration shape

A Service or System is a plain Python class. Class-level annotations of type [`Node`](/concepts/nodes) declare what it depends on; `__init__` initializes them.

```python theme={null}
from uniac import System, load
from db import Db        # generated stub for a published Service
from cache import Cache  # generated stub for a published Service

class Api(System):
    db: Db
    cache: Cache

    def __init__(self, log_level: str = "info"):
        self.db = Db()
        self.cache = Cache()
        self.log_level = log_level

service = load(Api)
```

`load()` constructs the instance, validates that every annotated `Node` slot is filled, and hydrates each `Node`'s `.url` from the deploy-time wiring. See [`load`](/sdk/load).

## Service vs System: when to use which

* Use **Service** (`kind=lib`) for code you want other packages to consume — a database client, a logger, a feature flag reader. Publish it with `uniac build`.
* Use **System** (`kind=app`) for the unit you deploy. A System pulls Services together and exposes the public surface (HTTP, jobs, scheduled work).

A Service can depend on other Services. A System can depend on Services. Services never depend on Systems.

## No magic

The framework does **not** auto-instantiate annotated Nodes. The annotation is a declaration; the value comes from your `__init__`. `load()` validates after construction and raises [`UniacValidationError`](/sdk/exceptions) if any slot is unset or holds the wrong type.

There is no base-class `__init__` to call. If you don't need init args, omit `__init__` entirely.
