Silex v0.47.1 / Docs Canonical source ↗

Define a package with Package.json

Package.json lives at the root of an application or package. It describes the project's sources, required packages, and, for a published package, its identity and any native files it uses.

Intention Fields
Identify and present the package name, version, description, authors, repository, requires
Select sources sources
Build the package graph dependencies, devDependencies
Share a namespace extensions, catalogs
Prepare a native integration boundary, artifacts

An application may need only sources and its dependencies. Fields that grant a namespace, open catalogs, or declare a native boundary belong to a named package.

Identify and present the package

A package intended for sharing declares at least its name, version, and Silex compatibility:

{
  "name": "MyPackage",
  "version": "1.0.0",
  "description": {
    "en": "Reusable utilities for Silex applications.",
    "fr": "Outils réutilisables pour les applications Silex."
  },
  "authors": ["Matanek"],
  "requires": {
    "silex": ">=0.44.0"
  }
}

name is the identity used by dependencies and imports. A local package folder has the same name. version uses MAJOR.MINOR.PATCH. Once published, its bytes cannot be replaced.

requires.silex begins with an inclusive minimum. Prefer an open range such as ">=0.44.0": it allows the package to be used with later Silex releases for as long as no incompatibility is known. In particular, it avoids blocking each new minor release as a precaution.

An exclusive maximum is also supported, for example ">=0.44.0 <0.45.0". This bounded range is less common: reserve it for a known incompatibility or a contract that must actually stop before that release. An installed package must declare its compatibility; a local package under development may still omit requires.silex.

Describe the package in one or more languages

A plain string applies to every language:

{
  "description": "Reusable utilities for Silex applications."
}

A localized object maps each language tag to its description, as in the first example. It must contain en. Silex checks the exact language, then its primary language — fr for fr-FR — and finally en.

Each text must be one non-empty line with no surrounding whitespace. Language tags are compared case-insensitively and cannot be repeated.

authors is an optional array of unique, non-empty names. Their order is preserved. This field attributes the work; it grants no right over the registry, namespace, or sources.

repository is an optional HTTPS GitHub URL for the package's development. It helps contributors find the source repository. The registry stores the files sent from the local directory; this URL neither supplies those files nor proves ownership of a package name.

Select sources

sources selects the portable source folder relative to the manifest:

{
  "sources": "Sources"
}

The default is Module. The value "." selects the project root. A manifest accepts exactly one folder, with no absolute path, backslash, glob, array, empty segment, or internal . or .. segment.

The same value is reused below the Platform/<OS>/ and Target/<target>/ roots. The mapping from these physical files to logical modules is explained in the language's package boundaries.

Declare dependencies

dependencies contains packages required by distributed code. devDependencies contains only tools used to develop, test, demonstrate, or measure the package:

{
  "dependencies": {
    "STD": "^0.20.0"
  },
  "devDependencies": {
    "GFX.Viewer": "^0.3.0"
  }
}

^1.4.0 accepts the requested version and newer releases with the same major number. =1.4.0 selects exactly that version. This rule also applies during the 0.x series: ^0.7.0 accepts 0.8.0, but not 1.0.0.

A package cannot appear in both objects. Consumers see only dependencies and must still directly declare every package they import. devDependencies join only the root package's development graph; they do not propagate recursively.

The command that prepares this graph is documented in Install and select packages.

Authorize composition between packages

extensions authorizes separately distributed child packages. catalogs opens facade modules to contribute blocks. This is the relevant excerpt from the GFX manifest:

{
  "extensions": {
    "GFX.Physics": {
      "friend": true
    },
    "GFX.UI": {
      "suite": true
    },
    "GFX.GPU": {
      "friend": true,
      "suite": true
    }
  },
  "catalogs": ["GFX.Components", "GFX.Plugins", "GFX.Resources"]
}

An empty entry such as "GFX.UI": {} authorizes only the child's identity. An exact entry may add three independent permissions:

  • friend opens the parent's package declarations to the child;
  • suite makes the child selectable by the parent's --suite installation;
  • merge allows additive public composition of the exact primary module.

The Parent.* wildcard covers direct children only. It may carry friend, but not suite or merge.

catalogs is independent from these permissions: only that field opens named modules to contributions. Any named package may contribute, whether it is a child or external package, provided it declares the catalog owner as a direct dependency. Participation grants no friend, suite, or merge permission and no part of the owner's namespace. The visibility and composition effects are detailed in package boundaries and re-exports.

Declare a native boundary

boundary describes private native inputs that the compiler may link for one target. Each branch contains named providers:

{
  "boundary": {
    "macos-arm64": {
      "providers": {
        "Native": {
          "archive": "Boundary/macos-arm64/libNative.a",
          "frameworks": ["CoreFoundation"]
        }
      }
    },
    "linux-x64": {
      "providers": {
        "Native": {
          "archive": "Boundary/linux-x64/libNative.a",
          "libraries": ["m", "pthread"]
        }
      }
    }
  }
}
Provider field Role
archive Static archive relative to the package and compatible with the target
frameworks Named Apple frameworks, on macOS only
libraries Named system libraries, without paths or raw linker options
requires Other providers in Package.Provider form

A provider declares at least one of these inputs. It may contain only a system library, framework, or another provider and then needs no dummy archive. A requirement may target the package itself or a direct dependency, for example "requires": ["GFX.SDL3"].

Silex selects only the active target branch. When an archive is declared, its format and architecture must match that target. The boundary remains private to the package: consumers see its public Silex API, not foreign archives, frameworks, libraries, or symbols. Source code that calls a provider is documented in Connect a package to a system API.

Prepare verified artifacts

artifacts describes large files needed for each target. An archive used by boundary can be prepared at the expected path:

{
  "artifacts": {
    "macos-arm64": {
      "Native": {
        "path": "Boundary/macos-arm64/libNative.a",
        "url": "https://example.com/releases/libNative.a",
        "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
      }
    }
  }
}

path stays inside the package, and sha256 contains the 64 hexadecimal digits of the expected digest. url is optional; when present, it uses HTTPS and lets a local package fetch a missing file during preparation. silex publish requires the declared file to be present and match its digest, then uploads it as a separate registry object. silex install of a published version reads that object from the registry without relying on the development URL. Compilation never downloads a file.

artifacts therefore prepares a file, while boundary decides how that file participates in native linking. The fields are independent: an archive already included among the sources needs no artifacts entry.

Validate the manifest

Before publishing a package, validate its identity, version, and current-target contract:

silex check MyPackage

To prepare artifacts for another target, then use --target with silex install or silex link. See Develop with local packages and Publish a package in the registry for the complete workflows.

Back to tools · Install and select packages · Understand package boundaries