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

# Environments & Packages Best Practices

> Organize your semantic models using environments and packages

Choosing the right structure for your environments and packages is essential for scaling your semantic modeling practice. This guide explores common organizational patterns and helps you decide which approach fits your team.

## Understanding Environments & Packages

### What is a Package?

A **Malloy package** is a directory of `.malloy` and `.malloynb` (notebook) files with a package manifest (`publisher.json`). The manifest contains the package name, version, and description. Packages are the fundamental unit of semantic model deployment in Credible.

```
my-package/
├── publisher.json          # Package manifest
├── ecommerce.malloy       # Semantic models
├── marketing.malloy
└── data/
    └── lookups.csv        # Optional embedded data
```

### What is an Environment?

An **environment** is a container that holds:

* **Database connections** - Shared across all packages in the environment
* **Packages** - Multiple versioned packages

Environments define the boundary for connection access and provide organizational structure for related semantic models. Access control can be configured at the organization, environment, and package levels with hierarchical inheritance.

### Key Concepts

**Connections are scoped to environments**: All packages within an environment share the same database connections. Users with environment-level `modeler` permissions can use these connections to build models, and users with `viewer` permissions can use connections to run queries.

**Packages have versions**: Each time you publish, you create a new version. One version can be **pinned as "latest"** (the default version users get). You can also **publish without pinning** to test new versions before promoting them.

## Patterns

There are multiple ways to organize environments and packages depending on your needs. The most common patterns are using separate environments for dev/staging/prod, and using multiple packages within a single environment with version management.

### Pattern 1: Multiple Environments (dev / staging / prod)

Use separate environments for each deployment stage, each with its own database connections.

```
Organization: acme-corp
├── Environment: dev-analytics
│   ├── Connection: dev-snowflake (→ dev.snowflake.com)
│   └── Package: sales-model v1.2.3
├── Environment: staging-analytics
│   ├── Connection: staging-snowflake (→ staging.snowflake.com)
│   └── Package: sales-model v1.2.3
└── Environment: prod-analytics
    ├── Connection: prod-snowflake (→ prod.snowflake.com)
    └── Package: sales-model v1.2.0
```

**When to use:**

* You have different database connections for each deployment stage
* You need strong separation between dev and production
* You want to test models against non-production data before promoting

**Workflow:**

1. Develop models in `dev-analytics` environment using dev connections
2. Publish and test the new version in dev
3. When ready, publish the same package version to `staging-analytics`
4. After validation, publish to `prod-analytics` and pin as latest

### Pattern 2: Single Environment with Multiple Packages

Use multiple packages within a single environment and manage releases through versioning.

```
Environment: analytics
├── Package: marketing-models
├── Package: sales-models
├── Package: finance-models
├── Package: core-models
└── Connection: enterprise-warehouse (shared)
```

**When to use:**

* Small to mid-size teams
* Single data warehouse or shared connections
* Collaborative culture where teams work together
* You want to manage releases through package versioning rather than environment separation

**Benefits:**

* Simpler access control (one environment)
* All packages share connections
* Easy cross-package development and collaboration
* Use versioning to manage releases and testing

## Package Versioning Best Practices

### Version Numbering

Use semantic versioning in `publisher.json`:

```json theme={null}
{
  "name": "sales-model",
  "version": "1.2.3",
  "description": "Sales analytics semantic model"
}
```

* **Major (1.x.x)**: Breaking changes (rename fields, remove views)
* **Minor (x.2.x)**: New features (add dimensions, new views)
* **Patch (x.x.3)**: Bug fixes, documentation

### Pinned or Latest Version

When you publish a package, you choose:

* **Publish and pin as latest**: This version becomes the default for all consumers
* **Publish without pinning**: Creates the version but doesn't change what users get by default

**Testing workflow:**

This is a two-step process:

1. **Publish & validate**: Publish the new version without pinning. Test and validate with a small group who explicitly request the new version.
2. **Pin as latest**: Once validated, pin the version as latest to serve it to everyone as the default.

## Next Steps

<CardGroup cols={3}>
  <Card title="Users & Groups" icon="users-gear" color="#988962" href="/platform-admin/groups-permissions">
    Learn how permissions work across environments and packages
  </Card>

  <Card title="Publishing Models" icon="rocket" color="#628698" href="/how-to/modeling/publishing">
    Step-by-step guide to publishing and versioning packages
  </Card>

  <Card title="CI/CD Integration" icon="arrows-rotate" color="#988962" href="/platform-admin/cicd">
    Automate deployments with CI/CD workflows
  </Card>
</CardGroup>
