Skip to main content
Choosing the right structure for your projects 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 Projects & 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 a Project?

A project is a container that holds:
  • Database connections - Shared across all packages in the project
  • Packages - Multiple versioned packages
Projects define the boundary for connection access and provide organizational structure for related semantic models. Access control can be configured at the organization, project, and package levels with hierarchical inheritance.

Key Concepts

Connections are scoped to projects: All packages within a project share the same database connections. Users with project-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 projects and packages depending on your needs. The most common patterns are environment-based projects (separating dev, staging, and production) and using multiple packages within a single project with version management.

Pattern 1: Environment-Based Projects

Use separate projects for different environments (development, staging, production).
Organization: acme-corp
├── Project: dev-analytics
│   ├── Connection: dev-snowflake (→ dev.snowflake.com)
│   └── Package: sales-model v1.2.3
├── Project: staging-analytics
│   ├── Connection: staging-snowflake (→ staging.snowflake.com)
│   └── Package: sales-model v1.2.3
└── Project: prod-analytics
    ├── Connection: prod-snowflake (→ prod.snowflake.com)
    └── Package: sales-model v1.2.0
When to use:
  • You have different database connections for each environment
  • You need environment separation (dev vs production)
  • You want to test models against non-production data before promoting
Workflow:
  1. Develop models in dev-analytics project using dev connections
  2. Publish and test new version in dev
  3. When ready, publish same package version to staging-analytics
  4. After validation, publish to prod-analytics and pin as latest

Pattern 2: Single Project with Multiple Packages

Use multiple packages within a single project and manage releases through versioning.
Project: 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 project)
  • 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:
{
  "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

I