Convert Figma logo to code with AI

numtide logodevshell

Per project developer environments

1,216
87
1,216
82

Top Related Projects

A fast, persistent use_nix/use_flake implementation for direnv [maintainer=@Mic92 / @bbenne10]

12,422

unclutter your .profile

21,846

Extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more

39,014

Simple Python version management

16,078

Manage your app's Ruby environment

A conda-forge distribution.

Quick Overview

Devshell is a command-line tool and Nix flake for creating reproducible development environments. It allows developers to define project-specific shells with custom packages, environment variables, and commands, ensuring consistent development setups across different machines and team members.

Pros

  • Reproducible development environments across different machines and team members
  • Easy integration with Nix and Nix flakes for declarative configuration
  • Supports multiple programming languages and tools
  • Allows for project-specific customization of shells and commands

Cons

  • Requires knowledge of Nix and its ecosystem, which can have a steep learning curve
  • May have limited support for non-Linux operating systems
  • Dependency on Nix can be seen as overhead for smaller projects
  • Documentation could be more comprehensive for newcomers

Getting Started

To get started with Devshell, follow these steps:

  1. Install Nix on your system (if not already installed):

    curl -L https://nixos.org/nix/install | sh
    
  2. Enable Nix flakes (if not already enabled):

    mkdir -p ~/.config/nix
    echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
    
  3. Create a flake.nix file in your project root:

    {
      description = "My project devshell";
    
      inputs.devshell.url = "github:numtide/devshell";
    
      outputs = { self, nixpkgs, devshell }:
      let
        system = "x86_64-linux";
        pkgs = import nixpkgs { inherit system; };
      in
      {
        devShell.${system} = devshell.legacyPackages.${system}.mkShell {
          imports = [ (devshell.lib.importTOML ./devshell.toml) ];
        };
      };
    }
    
  4. Create a devshell.toml file to define your development environment:

    [devshell]
    packages = [ "nodejs" "yarn" ]
    
    [[commands]]
    name = "hello"
    help = "Print hello world"
    command = "echo Hello, World!"
    
  5. Enter the development shell:

    nix develop
    

This setup creates a basic development environment with Node.js and Yarn, and a custom "hello" command. Adjust the devshell.toml file to fit your project's needs.

Competitor Comparisons

A fast, persistent use_nix/use_flake implementation for direnv [maintainer=@Mic92 / @bbenne10]

Pros of nix-direnv

  • Seamless integration with existing direnv workflows
  • Automatic loading of Nix environments without manual activation
  • Supports caching of Nix environments for faster subsequent loads

Cons of nix-direnv

  • Requires additional setup and configuration compared to devshell
  • May have a steeper learning curve for users unfamiliar with direnv
  • Limited to Nix-based environments, less flexible for non-Nix projects

Code Comparison

nix-direnv:

use nix

devshell:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  buildInputs = [ pkgs.hello ];
}

Key Differences

  • nix-direnv focuses on integrating Nix with direnv, while devshell provides a more comprehensive development environment solution
  • devshell offers a higher-level abstraction for defining development environments, making it easier to manage complex setups
  • nix-direnv is more lightweight and can be easily added to existing projects, whereas devshell may require more significant changes to project structure

Use Cases

  • nix-direnv: Ideal for projects already using direnv or those requiring quick Nix environment integration
  • devshell: Better suited for projects needing a more structured and feature-rich development environment, especially those heavily relying on Nix
12,422

unclutter your .profile

Pros of direnv

  • Language-agnostic and works with various shells (bash, zsh, fish)
  • Automatically loads/unloads environment variables when entering/exiting directories
  • Lightweight and easy to integrate into existing workflows

Cons of direnv

  • Requires manual setup of .envrc files in each project directory
  • Limited to environment variable management, lacks advanced development environment features
  • Potential security risks if .envrc files are not properly gitignored

Code Comparison

direnv:

# .envrc
export DATABASE_URL="postgresql://user:pass@localhost/mydb"
export API_KEY="secret_key"

devshell:

# devshell.toml
[devshell]
packages = ["postgresql", "nodejs", "yarn"]

[[commands]]
name = "start-dev"
command = "yarn start"

Key Differences

  • direnv focuses on environment variable management, while devshell provides a more comprehensive development environment setup
  • devshell is Nix-based and offers reproducible environments, whereas direnv is more flexible but less standardized
  • direnv works by modifying the shell environment directly, while devshell creates isolated environments for each project

Use Cases

  • direnv: Quick and easy environment variable management across multiple projects
  • devshell: Comprehensive development environment setup for Nix-based projects with reproducible builds
21,846

Extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more

Pros of asdf

  • Supports multiple programming languages and tools in a single system
  • Allows version management for each project independently
  • Has a large community and extensive plugin ecosystem

Cons of asdf

  • Requires manual installation and configuration of plugins
  • May have slower shell startup times due to its comprehensive nature
  • Can be more complex to set up initially compared to simpler alternatives

Code Comparison

asdf:

asdf plugin add nodejs
asdf install nodejs 14.17.0
asdf global nodejs 14.17.0

devshell:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  buildInputs = [ pkgs.nodejs-14_x ];
}

Key Differences

devshell focuses on creating reproducible development environments using Nix, while asdf is a more general-purpose version manager for multiple languages and tools. devshell integrates seamlessly with Nix ecosystems, providing a declarative approach to environment setup. asdf offers greater flexibility across different systems and languages but requires more manual configuration.

devshell excels in Nix-based workflows and offers better integration with Nix packages, while asdf provides a more universal solution for managing tool versions across various projects and languages. The choice between the two depends on the specific needs of the project and the preferred development ecosystem.

39,014

Simple Python version management

Pros of pyenv

  • Specialized for Python version management
  • Supports a wide range of Python versions and implementations
  • Allows per-project Python version configuration

Cons of pyenv

  • Limited to Python environments only
  • Requires manual installation of Python versions
  • Less integrated with system-wide package management

Code Comparison

pyenv:

pyenv install 3.9.0
pyenv local 3.9.0
python --version

devshell:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  buildInputs = [ pkgs.python39 ];
}

Key Differences

  • devshell provides a more comprehensive development environment setup, while pyenv focuses solely on Python version management
  • devshell leverages Nix for reproducible environments across different systems, whereas pyenv relies on system-specific installations
  • pyenv offers finer-grained control over Python versions, including patch-level specificity
  • devshell integrates better with other tools and languages in a project's ecosystem

Use Cases

  • Choose pyenv for projects requiring specific Python versions or multiple Python environments
  • Opt for devshell when working on projects with diverse language requirements or when seeking a more holistic development environment solution
16,078

Manage your app's Ruby environment

Pros of rbenv

  • Specifically designed for Ruby version management
  • Lightweight and focused on a single language ecosystem
  • Large community and extensive plugin support

Cons of rbenv

  • Limited to Ruby environment management
  • Requires additional tools for dependency management (e.g., Bundler)
  • Less flexible for multi-language projects

Code Comparison

rbenv:

rbenv install 3.0.0
rbenv global 3.0.0
rbenv rehash

devshell:

{ pkgs ? import <nixpkgs> {} }:
pkgs.devshell.mkShell {
  imports = [ (pkgs.devshell.importTOML ./devshell.toml) ];
}

Key Differences

  • rbenv focuses on Ruby version management, while devshell provides a more general-purpose development environment solution
  • devshell leverages Nix for reproducible environments across multiple languages and tools
  • rbenv requires manual installation of Ruby versions, whereas devshell can declaratively specify all required dependencies
  • devshell offers more flexibility for complex project setups and multi-language environments
  • rbenv has a simpler learning curve for Ruby-specific projects, while devshell may require more initial setup but provides greater long-term benefits for diverse development needs

A conda-forge distribution.

Pros of Miniforge

  • Supports multiple operating systems (Windows, macOS, Linux)
  • Provides pre-configured environments for data science and machine learning
  • Integrates seamlessly with the Conda package manager ecosystem

Cons of Miniforge

  • Larger installation footprint compared to lightweight alternatives
  • May have slower environment creation and package installation times
  • Less flexible for custom development environments outside of data science

Code Comparison

Miniforge (environment.yml):

name: myenv
channels:
  - conda-forge
dependencies:
  - python=3.9
  - numpy
  - pandas

Devshell (devshell.toml):

[devshell]
packages = ["python39", "python39Packages.numpy", "python39Packages.pandas"]

Miniforge focuses on creating reproducible environments for data science and scientific computing, while Devshell provides a more general-purpose development environment solution. Miniforge leverages the Conda package manager, which offers a wide range of pre-built packages for various platforms. Devshell, on the other hand, integrates with Nix and provides a more flexible approach to defining development environments, allowing for easier customization across different projects and languages.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

devshell - like virtualenv, but for all the languages

STATUS: unstable

Devshell Dev Environment Support room on Matrix

The goal of this project is to simplify per-project developer environments.

Imagine, a new employee joins the company, or somebody transfers teams, or somebody wants to contribute to one of your Open Source projects. It should take them 10 minutes to clone the repo and get all of the development dependencies.

Documentation

See docs (docs source)

Features

Compatible

Keep it compatible with:

  • nix-shell
  • direnv
  • nix flakes

Clean environment

pkgs.stdenv.mkDerivation and pkgs.mkShell build on top of the pkgs.stdenv which introduces all sort of dependencies. Each added package, like the pkgs.go in the "Story time!" section has the potential of adding new environment variables, which then need to be unset. The stdenv itself contains either GCC or Clang which makes it hard to select a specific C compiler.

This is why mkShell builds its environment from a builtins.derivation.

direnv loads will change from:

direnv: export +AR +AS +CC +CONFIG_SHELL +CXX +HOST_PATH +IN_NIX_SHELL +LD +NIX_BINTOOLS +NIX_BINTOOLS_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_BUILD_CORES +NIX_BUILD_TOP +NIX_CC +NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu +NIX_CFLAGS_COMPILE +NIX_ENFORCE_NO_NATIVE +NIX_HARDENING_ENABLE +NIX_INDENT_MAKE +NIX_LDFLAGS +NIX_STORE +NM +OBJCOPY +OBJDUMP +RANLIB +READELF +RUSTC +SIZE +SOURCE_DATE_EPOCH +STRINGS +STRIP +TEMP +TEMPDIR +TMP +TMPDIR +buildInputs +buildPhase +builder +builtDependencies +cargo_bins_jq_filter +cargo_build_options +cargo_options +cargo_release +cargo_test_options +cargoconfig +checkPhase +configureFlags +configurePhase +cratePaths +crate_sources +depsBuildBuild +depsBuildBuildPropagated +depsBuildTarget +depsBuildTargetPropagated +depsHostHost +depsHostHostPropagated +depsTargetTarget +depsTargetTargetPropagated +doCheck +doInstallCheck +docPhase +dontAddDisableDepTrack +dontUseCmakeConfigure +installPhase +name +nativeBuildInputs +out +outputs +patches +preInstallPhases +propagatedBuildInputs +propagatedNativeBuildInputs +remapPathPrefix +shell +src +stdenv +strictDeps +system +version ~PATH

to:

direnv: export +DEVSHELL_DIR +PRJ_DATA_DIR +PRJ_ROOT +IN_NIX_SHELL +NIXPKGS_PATH ~PATH

There are new environment variables useful to support the day-to-day activities:

  • DEVSHELL_DIR: contains all the programs.
  • PRJ_ROOT: points to the project root.
  • PRJ_DATA_DIR: points to $PRJ_ROOT/.data by default. Is used to store runtime data.
  • NIXPKGS_PATH: path to nixpkgs source.

Common utilities

The shell comes pre-loaded with some utility functions. I'm not 100% sure if those are useful yet:

  • menu - list all the programs available

MOTD

When entering a random project, it's useful to get a quick view of what commands are available.

When running nix-shell or nix develop, mkShell prints a welcome message:

🔨 Welcome to devshell

[[general commands]]

  hello         - prints hello
  menu          - prints this menu

[formatters]

  nixpkgs-fmt   - Nix code formatter for nixpkgs

[linters]

  golangci-lint - golang linter

[utilites]

  hub           - github utility

[devshell]$ 

Configurable with a TOML file

You might be passionate about Nix, but people on the team might be afraid of that non-mainstream technology. So let them write TOML instead. It should handle 80% of the use-cases and falling back on Nix is always possible.

Bash completion by default

Life is not complete otherwise. Huhu.

Packages that contain bash completions will automatically be loaded by mkShell in nix-shell or nix develop modes.

Capture development dependencies in CI

With a CI + Binary cache setup, one often wants to be able to capture all the build inputs of a shell.nix. With mkShell capturing all of the development dependencies is as easy as:

nix-build shell.nix | cachix push <mycache>

Runnable as a Nix application

Devshells are runnable (via nix run). This makes it possible to run commands defined in your devshell without entering a nix-shell or nix develop session:

nix run '.#<myapp>' -- <devshell-command> <and-args>

This project itself exposes a Nix application; you can try it out with:

nix run 'github:numtide/devshell' -- hello

See here for more details.

TODO

A lot of things!

  • Documentation
    • Explain how all of this works and all the use-cases.
  • Testing
    • Write integration tests for all of the use-cases.
  • Lazy dependencies
    • This requires some coordination with the repository structure. To keep the dev closure small, it would be nice to be able to load some of the dependencies on demand.
  • Doctor / nix version check
    • Not everything can be nicely sandboxed. Is it possible to get a fast doctor script that checks that everything is in good shape?
  • Support other shells
    • What? Not everyone is using bash? Right now, support is already available in direnv mode.

Contributing

Docs

  1. Change files in docs/
  2. Run nix run .#docs
  3. Open docs

Benchmark

  1. See benchmark/README.md
  2. Run nix run .#bench

Commercial support

Looking for help or customization?

Get in touch with Numtide to get a quote. We make it easy for companies to work with Open Source projects: https://numtide.com/contact