# Migrating from project.el

A short guide for people who’ve been using Emacs’s built-in `project.el` and want to try Projectile. For the bigger picture (philosophical differences, feature gaps in either direction) see Projectile versus project.el; for a side-by-side mapping of commands and config knobs see the "Concept and command concordance" section there.

## Quick start

Install Projectile from MELPA (or NonGNU ELPA), enable the global mode, and bind a prefix key:

    (require 'projectile)
    (projectile-mode +1)
    (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)

`project.el’s `C-x p` keymap continues to work; Projectile’s keymap is independent. The prefix doesn’t have to be `C-c p` — many people use `s-p` or whatever else fits their setup.

That’s enough to get going. Most of `project.el’s commands have a direct Projectile counterpart (e.g. `C-x p f` becomes `C-c p f`, `C-x p p` becomes `C-c p p`).

## Behavioral differences worth knowing

A handful of places where Projectile doesn’t behave like `project.el`:

- Switching projects. `project-switch-project` opens a command menu; Projectile instead runs whatever’s in `projectile-switch-project-action` after picking a project (find-file by default). If you miss the menu UX, press kbd:[C-u s-p p] to get the `projectile-dispatch` menu after selecting a project (requires the optional `transient` dependency).

- Indexing strategies. Projectile has three (`native`, `hybrid`, `alien`) controlled by `projectile-indexing-method`. The default is `alien` and behaves like `project.el’s VC backend (delegates to `git ls-files`, `fd`, `find` etc.). Pick `native` if you need to work somewhere external tools aren’t available.

- `.projectile`. Projectile’s native config file is consulted only under `native` or `hybrid` indexing. Under `alien` (the default) it’s mostly ignored — the external tool’s ignore rules (`.gitignore` etc.) take over. So in most modern setups, `.projectile` doesn’t do much.

- Project types. Projectile auto-detects ~60 project types (Cargo, Maven, Mix, npm, etc.) and pre-fills `projectile-compile-project`, `projectile-test-project`, `projectile-run-project`, `projectile-install-project`, `projectile-package-project`, and `projectile-configure-project` with sensible defaults for each. There’s no equivalent in `project.el` — `project-compile` runs whatever `compile-command` happens to be.

- Buffer ownership. Projectile and `project.el` use slightly different rules to decide which buffers belong to a project. Don’t expect `projectile-kill-buffers` and `project-kill-buffers` to act on identical sets.

- Persistent caches. Projectile maintains a project-file cache (controlled by `projectile-enable-caching`) and a known-projects file (`projectile-known-projects-file`). The latter is roughly analogous to `project-list-file`, but the format differs.

## Configuration knob translation

Most knob-for-knob mappings are in the concordance table in the comparison page. A few common ones:

If you had | Use
--- | ---
`project-list-file` | `projectile-known-projects-file`
`project-vc-ignores` | `projectile-globally-ignored-files`, `projectile-globally-ignored-directories`, `projectile-globally-ignored-file-suffixes`, plus the project-local `.projectile`
`project-vc-extra-root-markers` | `projectile-project-root-files-bottom-up` (and its sibling defcustoms)
`project-prompter` | `projectile-completion-system` (`default`, i.e. `completing-read`, or a custom function)
`project-vc-name` | `projectile-project-name` set via `.dir-locals.el`
`project-list-exclude` | `projectile-ignored-projects` (list) or `projectile-ignored-project-function` (predicate)

## Things that don’t have a direct equivalent (yet)

A few `project.el` features have no real Projectile counterpart at the time of writing:

- `project-find-matching-buffer` (jump to the equivalent buffer in another project)

- `project-file-history-behavior` `'relativize` (file-name history rewritten across projects)

- `project-other-window-command` / `-other-frame-command` / `-other-tab-command` (prefix-style display redirection — we duplicate commands instead)

- Sparse-index support for Git

- `project-vc-merge-submodules` (explicit Git submodule strategy)

See the comparison page for the full list.

## Coexisting with project.el

You don’t have to pick one. `project.el` ships with Emacs and won’t go away, and several other packages (`xref`, `eglot`, modern compilation buffers) will reach for `project-current` regardless of whether Projectile is loaded.

In practice this means: enabling `projectile-mode` doesn’t disable `project.el`. Both keymaps coexist, both sets of commands are available via `M-x`. Just keep in mind that some features (e.g. modeline integration, idle file-existence caching) come from `projectile-mode` itself, so if you turn the mode off you lose them.