npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@scinddev/xcind

v0.0.3

Published

Slim shell wrapper around docker compose with per-application config

Readme

Xcind — Docker Compose Application Wrapper

Xcind is a slim shell wrapper around docker compose that automatically resolves compose files, environment files, and override variants based on a per-application configuration file (.xcind.sh).

Quick Start

  1. Install — use npm or the install script:

    # npm (recommended)
    npm install -g @scinddev/xcind
    
    # Or use the install script
    ./install.sh /usr/local
  2. Configure your application — create a .xcind.sh file in your application root:

    # .xcind.sh
    # For applications using standard compose.yaml / .env, an empty file is enough!
    # Defaults: XCIND_COMPOSE_FILES looks for compose.yaml, compose.yml,
    #           docker-compose.yaml, docker-compose.yml
    #           XCIND_ENV_FILES looks for .env
    #
    # Override only if your application needs something different:
    XCIND_ENV_FILES=(".env" ".env.local")
    XCIND_COMPOSE_DIR="docker"
    XCIND_COMPOSE_FILES=("compose.yaml" "compose.dev.yaml")
  3. Use it — from anywhere inside your application:

    xcind-compose up -d
    xcind-compose build
    xcind-compose exec php bash
    xcind-compose ps

How It Works

When you run xcind-compose, it:

  1. Walks upward from $PWD to find the nearest .xcind.sh (the "app root")
  2. Sources .xcind.sh to load application-specific configuration
  3. For each file pattern in the config, expands shell variables and checks if the file exists on disk
  4. For each existing file, also checks for an .override variant
  5. Assembles --env-file and -f flags and passes them to docker compose
  6. Forwards all your arguments to docker compose

Configuration Reference

The .xcind.sh file is a sourceable bash script. It may set the following variables:

XCIND_ENV_FILES

Array of environment file patterns, relative to the app root. Each file that exists on disk is passed via --env-file. For each file, an .override variant is also checked (e.g., .env.env.override).

Default: (".env")

XCIND_ENV_FILES=(".env" ".env.local" '.env.${APP_ENV}')

XCIND_COMPOSE_DIR

Optional subdirectory where compose files live, relative to the app root. If set, compose file patterns are resolved relative to this directory.

XCIND_COMPOSE_DIR="docker"

XCIND_COMPOSE_FILES

Array of compose file patterns, relative to XCIND_COMPOSE_DIR (or the app root if XCIND_COMPOSE_DIR is unset). Each file that exists on disk is passed via -f. For each file, an .override variant is also checked.

Default: ("compose.yaml" "compose.yml" "docker-compose.yaml" "docker-compose.yml")

This mirrors Docker Compose's own file discovery. Only files that actually exist on disk are used, so listing all four names is safe.

XCIND_COMPOSE_FILES=(
    "compose.common.yaml"
    'compose.${APP_ENV}.yaml'
    "compose.traefik.yaml"
)

XCIND_BAKE_FILES

Array of Docker Bake file patterns, relative to the app root. Reserved for future use. Currently tracked in xcind-config JSON output but not passed to docker compose.

XCIND_BAKE_FILES=("docker-bake.hcl")

Override Resolution

For files with a recognized extension (.yaml, .yml, .json, .hcl, .toml), the override variant inserts .override before the extension:

| Base file | Override variant | | ------------------------ | ------------------------------- | | compose.yaml | compose.override.yaml | | compose.common.yaml | compose.common.override.yaml | | docker-bake.hcl | docker-bake.override.hcl |

For all other files (like env files), .override is appended:

| Base file | Override variant | | ------------- | --------------------- | | .env | .env.override | | .env.local | .env.local.override |

Files that don't exist on disk are silently skipped — both the base file and its override variant.

Variable Expansion

File patterns support shell variable expansion. Variables are expanded at runtime, so environment-specific files work naturally:

XCIND_COMPOSE_FILES=(
    "compose.common.yaml"
    'compose.${APP_ENV}.yaml'    # Note: single quotes to prevent premature expansion
)

With APP_ENV=dev, xcind checks for compose.dev.yaml and compose.dev.override.yaml. With APP_ENV=prod, it checks for compose.prod.yaml and compose.prod.override.yaml.

Commands

xcind-compose

The main workhorse. Resolves config and passes everything through to docker compose.

xcind-compose up -d
xcind-compose build --no-cache
xcind-compose exec php bash
xcind-compose down --remove-orphans

xcind-config

Dumps the resolved configuration. Useful for debugging and for the JetBrains plugin.

xcind-config              # JSON output
xcind-config --preview    # Show the docker compose command line
xcind-config --files      # List resolved files

Environment Variable Override

Set XCIND_APP_ROOT to bypass automatic root detection:

XCIND_APP_ROOT=/path/to/app xcind-compose up

Tab Completion

Since xcind-compose passes everything through to docker compose, you can reuse Docker Compose's completion. Add to your shell config:

# If using the Docker CLI's built-in completion:
complete -F _docker_compose xcind-compose 2>/dev/null

Direnv Integration

Xcind works independently of direnv. If you use direnv, you can optionally source .xcind.sh from your .envrc to get the config variables in your shell:

# .envrc
source_env .xcind.sh

JetBrains Plugin

The xcind-config command outputs JSON compatible with the xcind JetBrains plugin. Point the plugin at the xcind-config script path, and it will resolve compose files and env files for your IDE's Docker integration.

Installation

npm (recommended)

# Global install
npm install -g @scinddev/xcind

# Or run directly with npx
npx -p @scinddev/xcind xcind-compose up -d
npx -p @scinddev/xcind xcind-config --preview

Install script

# Install to /usr/local (may need sudo)
sudo ./install.sh

# Install to a custom prefix
./install.sh ~/.local

# Uninstall
sudo ./uninstall.sh
./uninstall.sh ~/.local

Nix

Xcind provides a Nix flake for installation and integration.

# Install imperatively
nix profile install github:scinddev/xcind

# Or run directly without installing
nix run github:scinddev/xcind -- up -d
nix run github:scinddev/xcind#xcind -- up -d

To use in another flake, reference the package output directly:

{
  inputs.xcind.url = "github:scinddev/xcind";

  outputs = { self, nixpkgs, xcind, ... }:
    let
      system = "x86_64-linux"; # or "aarch64-darwin", etc.
    in {
      devShells.${system}.default = nixpkgs.legacyPackages.${system}.mkShell {
        buildInputs = [ xcind.packages.${system}.default ];
      };
    };
}

Alternatively, use the overlay to access xcind as pkgs.xcind:

{
  inputs.xcind.url = "github:scinddev/xcind";

  # Add the overlay
  nixpkgs.overlays = [ xcind.overlays.default ];

  # Then use pkgs.xcind in your packages
  environment.systemPackages = [ pkgs.xcind ];
}

Docker

The published Docker image is available on GHCR:

docker pull ghcr.io/scinddev/xcind:latest

To use it, bind-mount your project directory into the container's /workspace and mount the Docker socket so docker compose can reach the daemon:

docker run --rm \
  -v "$PWD":/workspace \
  -v /var/run/docker.sock:/var/run/docker.sock \
  ghcr.io/scinddev/xcind:latest up -d

The image's entrypoint is xcind-compose, so any arguments are forwarded directly. To run xcind-config instead, override the entrypoint:

docker run --rm \
  -v "$PWD":/workspace \
  --entrypoint xcind-config \
  ghcr.io/scinddev/xcind:latest --preview

Development and testing

Build and run the test suite in a container:

docker compose build
docker compose run xcind

Test against a specific bash version:

docker compose build --build-arg BASHVER=5.1
docker compose run xcind

For an interactive shell, copy the override template:

cp compose.override.dist compose.override.yaml
docker compose run xcind

License

MIT — see LICENSE for details.

File Structure

xcind/
├── bin/
│   ├── xcind-compose          # Main executable — wraps docker compose
│   └── xcind-config           # Config dump — JSON, preview, file listing
├── lib/xcind/
│   └── xcind-lib.bash         # Shared library (sourced by other scripts)
├── test/
│   └── test-xcind.sh          # Test suite
├── examples/
│   ├── acmeapps/
│   │   └── .xcind.sh          # Simple example
│   └── advanced/
│       └── .xcind.sh          # Variable expansion example
├── contrib/
│   ├── release                # Release helper script
│   └── test-all               # Full test runner (Docker + unit)
├── docs/
│   └── releasing.md           # Release process documentation
├── compose.yaml               # Default Docker Compose configuration
├── compose.override.dist      # Compose override template
├── Dockerfile                 # Container image build
├── flake.nix                  # Nix flake (package + overlay)
├── flake.lock                 # Nix flake lock file
├── install.sh                 # Install to a PREFIX
├── uninstall.sh               # Remove from a PREFIX
├── package.json               # npm package manifest
├── LICENSE                    # MIT license
└── README.md