---
# System prepended metadata

title: Nimble features

---

# Nimble features

Nimble `feature`(variant) represents grouping of dependencies/compile flags that
are propagated to the consumers of a particular package. The main goal is to
isolate the dependencies that may or may not be required by upstream packages
and allow upstream packages to choose what set of functionality is enabled for
their needs.

Syntax for the nimble file:

```nim
....

requires "foo +bar"

feature "featureOne":
  require "dep1@any +bar +baz" # feature specific
  --define: featureFlag # feature specific
  switch("app", "lib") # feature specific

if "featureOne" in getFeatures():
  echo "featureOne is enabled"
```

Then you can check compile time from the `nim` file if the feature is enabled:

``` nim

# nim file

when defined(feature.<packageName>.<featureName>):
  # assume the file is compiled with the feature <featureName> on.
```

1. The enabled features are enumerated after the package name or the version
   like `foo feature1 feature2` or `foo@bar feature1 feature2`. The syntax is
   geared towards the ability to allow exclusions like `foo@bar -feature1 -feature2`,
   or valued features like `foo@bar feature1=bar`. See at the end the
   alternative syntax proposals for expression features
3. The compile flags are stored in the nimble.paths file.
4. The features are disabled by default when requiring a package.
5. File containing the enabled features is added to the package cache to make
   sure the hash is different based on the passed features.
6. Nimble lock files store each feature with what flags is installed. By default
   when you perform command like `lock`, `build`, `install` and `test` all
   features will be on. If you want to specify specific set of features to be on
   you can pass `--features` flag. For example: `nimble lock --features=[featureOne,featureTwo] --lock-file nimble-OneTwo.lock`.
7. A methods for returning the compilation flags and enabled features in `nimble`
   script API are introduced for the purpose of running `nim` ad-hoc in the
   `nimble` file.

## Examples
* Given the following dependency hierarchy:

```
- foo
  - bar1
    - baz{featureOne}
  - bar2
    - baz{featureTwo}
```

Package `foo` will be compiled against package `baz{featureOne, featureTwo}`(i.
e. the features are composed).

## Possible feature syntaxes:

* `require foo@bar +feature1 +feature2`
* `require foo@bar{feature1, feature2}`
* `require foo@bar[feature1, feature2]`

Here are alternative feature syntaxes. Note that the syntax should support
evolving to the ability to exclude feature(-feature), and the ability to have
features with value (-feature=value)