Configuring Visual Studio Code

Last updated on
24 March 2026

tl;dr

If you are in hurry…


Overview

Difference between "Visual Studio" and "Visual Studio Code"

Logo of the Microsoft Visual Studio IDEMicrosoft has been present in the IDE market since 1997. Visual Studio specializes in working with mostly Microsoft-related programming languages like C#, .NET, C++, and other technologies. It is a full-featured, proprietary integrated development environment (IDE), primarily designed for Windows, offering advanced debugging, profiling, and project management features. It is available in Community (free), Professional, and Enterprise (paid) editions.

Logo of the Visual Studio Code (aka. VS Code) IDE After almost 2 decades, an entirely different IDE, Visual Studio Code (or VS Code for short), was published in 2015, specialized for working with web-related technologies like JavaScript, TypeScript, Node.js, CSS & HTML, among others. It is a free, open-source, cross-platform code editor, built on the Electron framework, and designed to be lightweight and extensible via a rich extension marketplace. It supports many programming languages and tools – including Git integration and debugging – primarily through user-installed extensions rather than built-in functionality.

Note: Despite what their similar names and logos might suggest, Visual Studio and Visual Studio Code have very few characteristics (if any) in common.

Difference between "VS Code" and "VS Codium"

Logo of the VS Codium IDE VS Codium is a community-driven, freely licensed binary distribution of Microsoft’s IDE, VS Code. Further details quoted from the "Why does this exist?" section of the website of VS Codium:

"Microsoft’s vscode source code is open source (MIT-licensed), but the product available for download (Visual Studio Code) is licensed under this not-FLOSS license and contains telemetry/tracking. […]"

The naming logic intentionally follows the same pattern as the proprietary Google Chrome vs. the open-source Chromium web browsers. Since hundreds of Drupal community members have proven in recent decades that they stand firmly beside the FLOSS ideology, this guide uses screenshots from the VS Codium variant of the software. However, most (if not all) solutions shared here should work similarly (or the same) with Microsoft's VS Code as well. The same applies to other builds (like the Code OSS for Linux) and forks of VS Code produced by different software vendors:

This guide was written to be as system-agnostic as possible. Even though its screenshots were taken on macOS, the knowledge shared here should also apply to Windows and Linux.

The Drupal installation that is demonstrated in this guide uses a common installation profile:

  • Project codebase based on the drupal/core-recommended meta-package
  • drupal/core-dev package also installed by Composer ($ ddev composer require --dev drupal/core-dev)
  • Containerized underlying stack
  • The development tool used is DDEV

The target audience here is Drupal developers working on complete website projects. If you're contributing to community modules, themes, or Drupal Core itself, you might have different preferences, so you may need to adjust your settings accordingly.

Levels of supporting PHP

At the time of writing (July 2025), Microsoft's VS Code (and therefore all of its builds or forks) only natively supports PHP programming to a limited degree out of the box. Fortunately, there is a vibrant marketplace for sharing free or paid extensions and themes, and several extensions are available for PHP development, with overlapping feature sets. Their abundance actually makes choosing one difficult, so this guide aims to present first-hand experience of using them as a Drupal developer.

Let's assume you already have a build or fork of VS Code installed; for example, this is how VS Codium welcomes you:

Opening screen VS Codium IDE

This guide contains dozens of screenshots, each depicting valuable details. You can use the right-clickOpen image in new tab (or similar) feature of your browser, and they are also linked to the image file so you can click them to open them conveniently.

The IDE comes with some built-in features already available without any external plugins needed, for example:

  • Advanced UI for Git
  • Built-in terminal
  • Built-in debugger
  • Supporting "workspaces" to handle several projects separately
  • Global search within files in the directory structure

Feel free to customize the IDE according to the official documentation, which gives helpful advice.

Basic PHP support out of the box

Now, let's take a quick look at the basic level of PHP support our IDE offers us at this very initial state. First, ensure you have chosen a color theme for the editor; otherwise, the syntax highlighting might not be visible. When opening a PHP file with no specific IDE extension installed, some features already work. To mention a few:

  • Offers autocomplete suggestions
  • Detects syntax errors
  • Allows collapsing/folding sections of code
  • Performs search & replace
  • Shows an overview minimap on the right side
  • Changing all occurrences of a term (right-click on it)

Basic support for PHP language in VS Codium

It might be worth understanding the hierarchy of integration modules of programming languages in this IDE. VS Codium is shipped with pre-installed extensions for several programming languages and other technologies. You can check them by opening the Extension Browser panel on the primary (usually left) sidebar, and combining the following two filters:

@builtin @category:"programming languages"

As you can see, all extensions on this list are from the same vendor (vscode). (Although they have minimal impact on overall performance, some prefer disabling any they are not planning to use in the future.) Add a third filter option, "PHP", to the end of the query:

@builtin @category:"programming languages" PHP

These three parameters, separated by space characters, are different. The first two, starting with an 'at' character, are predefined filtering options. (The second one takes a string between double quote marks as an input value.) The third string narrows the list further to results mentioning the word "php" (case insensitive). Now a single extension remains on the result list.

Its fully qualified identifier is vscode.php-language-features, and this one is responsible for providing some of those basic features we saw earlier (you can check by temporarily disabling this built-in extension). Clicking on its cogwheel icon, then choosing the "Settings" option navigates us to the settings window of the IDE prefiltered specifically to those configuration options this built-in extension provides:

Prefiltered settings of a built-in extension in VS Codium

Alternatively, simply opening the IDE's settings window (Ctrl+comma or Cmd+comma), and manually filtering the list for the term "PHP", and choosing the "PHP" group on the left side of the tree structure, then some other (somewhat related) results also appear:

The default setting options related to PHP in VS Codium

One great feature of this IDE is that all its configuration is stored in an easily editable, plain text JSON file sitting somewhere in the OS user's home directory (exact location depends on the OS). If the IDE was installed recently, and nothing customized yet, then this settings.json file can look this short (or even empty):

{
    "files.associations": {
        "*.php": "php"
    },
    "php.validate.executablePath": ""
}

The configuration management works real-time: the software instantly reacts to any changes made within the settings.json file. It can be easily tried out by opening any *.module file from Drupal: once you already have a website project opened in the IDE, just type "media.module" in the Command Palette, then choose Drupal Core's module file:

Although we know this file is written in PHP, the IDE still displays it as plain text. That's because the ".module" file name extension is specific to Drupal, so we need to inform the IDE how to interpret such files in the future.

In the settings.json file, go to the "files.associations" key, select the entire line of "*.php": "php", search for and choose the "Duplicate Selection" option from the Command Palette. Check the Problems pane at the bottom: overwrite the key to "*.module", leave its value on "php", then add the missing comma to the end of the previous line.

{
    "files.associations": {
        "*.php": "php",
        "*.module": "php"
    },
    "php.validate.executablePath": ""
}

Once your JSON block looks like this, save the settings while keeping an eye on the tab of the still-open ".module" file. Its icon instantly changes, signifying that its associated file type has been updated. (Of course, Drupal also uses some other specific file name extensions, but we will deal with them later down on this guide – this was only for trying out the instant effect of changes in the settings.json file.)

Any changes to the settings.json file usually get respected instantly, but sometimes a restart of the IDE might be necessary.

A freshly installed IDE may have a clean setup, but in the future, repeatedly adding and removing dozens of extensions will make it much more complicated to know which extension is responsible for which settings.

Back to the settings of the PHP extension:

Prefiltered settings of a built-in extension in VS Codium

Three out of four already have a factory default value set, but the third one from the top ("Executable Path") requires us to open the settings.json file of the IDE. Clicking the link opens another editor tab with this file. 

Some features we will configure later on during this guide require a PHP parser to be installed on our (host) computer. To test whether the IDE can reach out to the binary of the PHP parser, you can use the "Tasks" feature of the IDE. Type "tasks open" into the Command Palette, select the "Tasks: open user tasks" option from the list, then copy over the following sample snippet into the editor opening the file (on macOS it is located at ~/Library/Application Support/VSCodium/User/tasks.json):

# A simple `tasks.json` file

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Display the version of the installed PHP binary",
      "type": "shell",
      "command": "php -v"
    }
  ]
}

After saving this tasks.json file, type "run task" into the Command Palette, choose the option with our "Display the version…" title, accept "Continue without scanning task output", then the IDE's built-in terminal pane should activate with the results of our $ php -v command:

Running a simple custom task in VS Codium

If you do not see the version number appear or an error is returned, the PHP binary might not be available on your host computer's global $PATH variable. Run the $ which php (or $ whereis php) command in a regular Terminal window to ensure you have installed the PHP binary. If it gets confirmed by responding when queried, then it's recommended to register it globally in the $PATH variable of your OS. If registering is not an option for some reason, then you can still inform the IDE to look for it on a specific path. In this example, it was installed with Homebrew, which installs at this absolute path:

# settings.json file

{
  ...
  "php.validate.executablePath": "/opt/homebrew/bin/php"
  ...
}

Now you know this versatile Tasks feature which might come handy in the future. Auto-saving files opened in editor windows are not enabled by default, so it's recommended to add the "files.autoSave": "afterDelay", line to your settings.json file. (Otherwise, find this option near the bottom of the File menu.)

Please note that if you use a fork of VS Code (eg. Cursor, Windsurf), then an other PHP-related extension, "PHP Language Basics" with the unique identifier vscode.php will also pop-up in extra in the list mentioned above:

An extra PHP extension appearing in Cursor and Windsurf IDEs

At this point, we've had a glimpse into the configuration management of the IDE. And we've also seen the basic level of support that VS Codium (or other builds/forks) have to offer for PHP programming out of the box. As Drupal developers, we expect a much deeper understanding of the codebase from our IDE, so let's continue with further integration.

Choosing a PHP parser

To let the IDE's internal language processor engine (branded as "IntelliSense") parse PHP files, thus "understand" their internal structure, we need specialized extensions. Still in the Extension Browser panel, delete the "@builtin" filter from our previous filter combination and add "@sort:installs" instead:

PHP @category:"programming languages" @sort:installs

Comparing their installation counters, we see that two extensions are competing with each other in terms of popularity:

PHP parser extensions available for installation in VS Codium

What is common between both of them is that they offer various coding assistance features on a freemium model. Let's take a closer look at each to understand their background better.

1. Intelephense by Ben Mewburn:

Logo of the Intelephense extension published by Ben MewburnBen Mewburn apparently is a standalone developer (GitHub profile) working on his single extension alone for 6 years as of now (first stable release in July 2019).
Unique identifier: bmewburn.vscode-intelephense-client
License price: 25 EUR (one-time payment, forever eligibility)
Installations: cca. ~605K
Links: Product pageMarketplace* | Source code


2. PHP Tools by Devsense:

Logo of the PHP Tools extension published by DevsenseDevsense is a company that specializes in developing and maintaining a suite of VSX extensions bundled into one package. 
Unique identifier: devsense.phptools-vscode
License price: 120 EUR, then 70 EUR for individuals (more expensive for company teams)
Installations: cca. ~556K
Links: Product page | Marketplace* | Documentation

*Unofficial builds and forks of VS Code are legally prohibited from installing extensions from Microsoft's own walled garden marketplace. Therefore an independent service, Open VSX Registry is available for all these IDEs to fetch extensions instead. Whenever "marketplace" is mentioned, this guide always refers to this Open VSX Registry, not Microsoft's.

Comparing PHP Tools with Intelephense

Comparing their functionality in practice suggests that the free version of PHP Tools covers the feature set of Intelephense almost entirely. These are mostly the following:

  • Displaying code structure of the active file in the Outline panel. Intelephense (on the left) shows the method/function parameters, but PHP Tools (on the right) displays their visibility instead:

  • View detailed parameter hints for call expressions. Intelephense displays more details in its pop-up:
    Intelephense PHP Tools

  • Find all references: quickly find symbol references within the entire workspace. 
    Intelephense PHP Tools

    Found 388 results in 168 files:

    Found 410 results in 174 files:

  • Code completion with context-aware suggestions, with automatic addition of use declarations
  • Go to definition: quickly navigate to symbol definitions
  • Symbol search: fast camel/underscore text search for workspace and document symbol definitions
  • Diagnostics: error tolerant parser and powerful static analysis engine report problems as you type
  • PSR12 compatible full document and range formatting
  • Support for "embedded languages", when PHP, JS, or CSS code appears within a HTML document
  • Detailed hover information with links to official PHP documentation
  • Smart highlighting of references and keywords
  • Both extensions support intelligent renaming of a class: its file also gets renamed. The only difference is that Intelephense does it fully automatically, but PHP Tools follows the "refactoring preview" method known from other IDEs (eg. PhpStorm). Stops at an extra manual step, allowing the user to review the proposed changes before hitting the "Apply" button.

Obviously, there are some differences as well.

  • They apply a different logic when counting references to functions/methods. For example, look at line #21 on the screenshot below. For Drupal Core's ConfigFormBase class, Intelephense reports 49 references, but PHP Tools shows 153 instead. The number of implementations matches.
  • PHP Tools shows a little yellow lightbulb icon (see at line #22 on the right side) to communicate local actions. For those coming from PhpStorm, it might seem more familiar.
  • Intelephense displays a link to the parent of a create() method (above line #54), PHP Tools does not.
  • Also, similarly to PhpStorm, PHP Tools inserts "inlay hints" to communicate the type constraints of method parameters and return values. With some extra effort, these short words can be formatted with different typography to make them easier to distinguish from the actual source code.

As you can see, both products offer advanced-level integration for the PHP programming language. Up to this point, only their assistance with editing PHP files was discussed. The upcoming sections will cover the configuration of other developer aids like DDEV, Composer, Xdebug, PHP CS, PHPUnit, etc.

Another essential distinction between the two might be helpful to point out. Intelephense is a single extension, which is mostly effective with editing PHP files, but PHP Tools is a bundle of three extensions, all of which can be helpful to manage a Drupal project.

So in conclusion, PHP Tools offers almost all of the functionality of Intelephense, all for free, plus other useful features.  The rest of this guide will rely on PHP Tools as the PHP parser of choice.

EditorConfig

If you've never heard about it, you might find their own description on their website helpful. Unfortunately, VS Code does not support it natively, but the friendly folks behind EditorConfig published and maintain an extension in the Open VSX Registry with the unique identifier editorconfig.editorconfig (998K installs on their marketplace page).

As a quick try-out, open any file, for example, the web/core/INSTALL.txt file of Drupal Core. Put a series of whitespace characters at the end of any line, then save the file: these unnecessary spaces are still present. However, the spaces are gone after enabling this extension and re-saving the file. This happens because Drupal Core in its root directory is shipped with an .editorconfig file containing some basic formatting rules, which the extension automatically detects and overrides the IDE's respective settings.

PHP CodeSniffer

The .editorconfig file in the previous section contains only the tip of the iceberg. The Drupal community has established its sophisticated coding standards through a series of discussions leading to an agreement, and therefore expects its contributors to abide by them. These much more elaborate expectations are described in various files at two locations, which might be worth clarifying right here before we continue.

  1. Checking the source code of Drupal Core itself, you'll see a phpcs.xml.dist file in its core/ directory. This file is meant exclusively for those working on the source code of Drupal Core directly.
  2. As this guide assumes your role is a developer working on custom modules or website projects for your clients, check out the Coder contrib project (docsrepository): it has a different phpcs.xml.dist ruleset file. Besides other reasons, this is why this guide requires having the drupal/core-dev metapackage (source code) installed by Composer in your project's codebase. It automatically copies over 2 ruleset files to the vendor/drupal/coder/coder_sniffer/ directory. 

There is a development tool called PHP CodeSniffer (PHP CS for short) responsible for processing these rulesets defined and informing the IDE user when the code currently edited does not comply with them. This process is called code linting, and these tools the linters. As we mentioned earlier, the marketplace offer a wide variety of extensions to integrate the PHP CodeSniffer tool with VS Codium builds/forks as well:

(At the time of writing, July 2025)

The situation resembles deciding which contrib module or theme you want to use in your Drupal project:

  • All of them are free of charge
  • One is deprecated, thus abandoned – the faded one at the right end
  • The names and logos of the rest do not really help distinguish them
  • You try to make your bet based on the number of installations

Before comparing them by functionality, let's define the prerequisites we expect from the perfect candidate:

  1. The least manual setup necessary – optimally, should work out-of-the-box
  2. Not only PHP CS, but PHP CBF should also work
  3. Define a formatting service for the IDE API
  4. Previous point allows us to use the "Format Document" option from the Command Palette
  5. Optionally, auto-detect the Drupal-specific ruleset (even less manual setup)

After trying them out one-by-one, I found that only valeryanm.vscode-phpsab (2K installs) meets our qualifications. The only setting that needs to be done manually is to point its settings to the ruleset files by adding this line to the settings.json. In most cases referencing them by their name as "phpsab.standard": "Drupal,DrupalPractice", should work. If not, then you may try specifying them by their full paths separated by a comma:

# settings.json file

{
  ...
  "phpsab.standard": "vendor/drupal/coder/coder_sniffer/Drupal/ruleset.xml,vendor/drupal/coder/coder_sniffer/DrupalPractice/ruleset.xml",
  ...
}

When you need to lint and fix code in a Docker container within your local IDE, but running a Dev Container is not an option for any reason, then an alternative solution can be the mtbdata.vscode-phpsab-docker (4,4K installs – available only from Microsoft's marketplace but not from Open VSX Registry) extension. It's a fork of valeryanm.vscode-phpsab while trying to maintain compatibility with that.

Feel free to skip this paragraph if you're not interested in the reasoning why other extensions were dismissed. Although wongjn.php-sniffer (20K) offers extensive configuration options and can be configured as the default formatter for PHP files, I still cannot make it work as expected. The stoildobreff.php-resolver (16K) defines itself as "It’s purpose is to try to provide all-in-one solution for resolving problems" on its page. Still, after installation, the PHPCS executable is not automatically detected. The main limitation of shevaua.phpcs (5.7K) is that it does not define itself as a formatter service. Another issue is that when checking the "author" key defined in its package.json (source code), it shows signs that it is highly similar (if not even forked – source code) from the abandoned ikappas.phpcs extension (seen greyed out on the marketplace screenshot above). Finally, when invoking the "Format Document" command with  obliviousharmony.vscode-php-codesniffer (4.3K) results in an ERROR: Class file for report "ObliviousHarmony\VSCodePHPCSIntegration\VSCodeIntegration" not found message.

PHPStan

First, it's essential to understand the key difference between PHP CS and PHPStan.

  • Abiding by coding standards is about beauty. Although ugly code may work mechanically, it's hard to read for humans. This is what PHP CS checks and PHP CBF fixes. (remember as "CS" = Coding Standards, "CBF" = Code BeautyFier.) See the previous section  for details.
  • On the other hand, static analysis discovers mechanically broken code. Even if it's beautifully formatted, it just simply does not work. This is where PHPStan ("STAN" = STatic ANalysis) comes into the picture.

Most dev tools offer out-of-the-box functionality, but getting PHPStan working requires some attention at the very beginning when setting up a project. You might want to read the related Drupal․org documentation to understand the background. Otherwise, if you have read this guide from its beginning, you might remember the prerequisite of Composer installing the drupal/core-dev. It's crucial because the following packages must be present in your vendor/ directory (in the order of their dependency chain):

drupal/core-dev
 ↳ phpstan/extension-installer
 ↳ mglaman/phpstan-drupal
   ↳ phpstan/phpstan-deprecation-rules

Create a ./phpstan.neon file with the following content. Add to the list the path of further directories where you have custom PHP-language files stored in your codebase (eg. web/themes/custom, if your custom themes has a .module file, for example). To share it with our teammates working on the same project, commit this file into VCS.

# The simplest possible form of a `phpstan.neon` file
# placed in the root directory of your codebase

parameters:
  level: max
  paths:
    - web/modules/custom

Install the sanderronde.phpstan-vscode (3,2K) extension from the marketplace, then look for the "PHPStan: Launch setup" command from the Command Palette. First, choose the "Automatically" option, then type the path of your config file previously created (provide only the filename "phpstan.neon" if you placed it into the root directory of your codebase). Hit Enter, then leave the pre-filled value of "vendor/bin/phpstan" as the path of the executable binary file. Hit Enter again, then finally choose the "Test setup" option to try out if the integration works as expected. If a "Test run successful!" message appears in the lower corner, you're good to go. Now, PHPStan is ready to detect functional errors in your files.

By default, the Problems panel lists errors from all files of your codebase reported by various tools. Use the filter option if you prefer to focus on errors only related to the file opened in the currently focused editor.

Xdebug

Supporting debugging by stepping through a computational process (or, in the case of backend development, an HTTP request-response cycle) is also a crucial feature we expect to have in an IDE. VS Codium has a "launch" functionality for this purpose to integrate external debugging tools with. Fortunately, the marketplace offering here is clearer than it was with PHP CS:

(At the time of writing, July 2025)

The two most installed ones – by their unique identifiers: felixfbecker.php-debug (338K) and xdebug.php-debug (161K) – represent the same xdebug/vscode-php-debug repository behind the scenes. However, when comparing their product pages within the IDE, the Details tab's right sidebar shows that the one published under the official "Xdebug" vendor name has much more recent versions released. Also, switching over to the Features tab, under the Commands section, it provides two extra commands. In general, xdebug/vscode-php-debug is more up-to-date overall.

Many might remember configuring Xdebug to make it work was not always easy in the last few years. Reading through the overwhelming amount of information on their marketplace page for both extensions might still not seem easy for some to follow. The good news is that setting up a launch.json definition for the IDE can be completed automatically thanks to our friends at the amazing DDEV community. As the Drupal community has announced DDEV as the officially recommended development tool, this guide assists with setting up VS Code-based IDEs, assuming one is using DDEV. As no manual tweaking is necessary to make Xdebug work properly with DDEV, others (eg. those still running Lando, for example) might benefit from sharing the default launch.json file defining the connection:

# Content of `.vscode/launch.json` file

{
  "configurations": [
    {
      "name": "Listen for Xdebug",
      "type": "php",
      "request": "launch",
      "hostname": "0.0.0.0",
      "port": 9003,
      "pathMappings": {
        "/var/www/html": "${workspaceFolder}" # Lando users: change it to '/app'
      },
      "preLaunchTask": "DDEV: Enable Xdebug", # Lando users: omit these 2 commands
      "postDebugTask": "DDEV: Disable Xdebug"
    }
  ]
}

The launch.json file is workspace-specific, so you can only store it either in the .vscode/ directory at the root of the project codebase or as part of your *.code-workspace file, but not in your OS user's preferences folder.

Once you have configured Xdebug, and the .vscode/ directory has been created, you must decide whether it should be committed to VCS or added to the .gitignore file. For further details you might want to check Drupal․org's documentation page dedicated to setting up Xdebug too.

DDEV

Containerization of the underlying software stack when running PHP-based CMSes, such as Drupal, is becoming increasingly widespread. It makes life much easier for a regular developer to maintain a web app, whether alone or as a team member. Although DDEV is not the only option for working with a Docker-based project structure, it is definitely among the most popular. Adding the biati.ddev-manager (3,5K installs) extension to your IDE makes Xdebug work out-of-the-box (see the previous section ) and provides a helpful GUI to manage containers right from your IDE without context switch.

The biati.ddev-manager extension works as expected out-of-the-box; manually, no initial setup is necessary. However, checking through its configuration options, four settings help us better understand the interoperability between these extensions:

  1. Automatically configure Workspace PHP: As discussed earlier in this guide, if either Ben Mewburn's Intelephense or Devsense's PHP Tools is installed and configured, the DDEV extension will play nicely with it.
  2. Automatically configure debugger: auto-wiring Xdebug works like a charm, but if not needed, you can disable this feature here.
  3. Docker provider: once configured, you can easily start the Docker provider (OrbStack in my case) from the Command Palette.
  4. Default database manager: a convenient feature for opening the database browser directly from the IDE (continue reading with the next section ).

Database browser

Before discussing how to add DB browsing functionality within your IDE, it might be worth noting that DDEV offers many other options to connect other GUI clients to your database service: see its documentation.

Many developers (especially those arriving from JetBrains products) might already be accustomed to the built-in database browser tool as part of their development workpad. VS Code and its builds/forks have no such built-in feature, but as usual, many solutions are available for installation through the marketplace.

Sticking with the same plan as we walked through this guide, we want to maximize the interoperability of extensions, so let's follow the recommendations from the DDEV extension. These are damms005.devdb (28K installs), dbcode.dbcode (36K installs), and cweijan.vscode-database-client2 (120K installs). The first one, DevDB, offers easy one-click configuration for DDEV, but it renders its UI in the Panel area of the IDE:

A minor disadvantage of DevDB is that it stores connection information at some internal location of the extension, but not in the IDE's settings.json. However, if you want to share the database connection information with your colleagues, or if you prefer a more traditional presentation of the DB tables (as PhpStorm does, for example), then here's how you can configure DBCode which has a more coherent GUI fitting better with VS Codium's look and feel.

Remember that DDEV tries to stick with the same five-digit port number between restarts. Still, in some circumstances, it might be reallocated to a different five-digit port number, which you will need to update here manually:

The cweijan.vscode-database-client2 works similarly to the previous ones:

PHPUnit

Similarly to the previous sections, the combination of installed extensions can cover a wider set of functionalities without adding any specific ones. This also applies to running PHPUnit tests: Devsense's PHP Tools extension pack supports automatic detection of test definitions (an icon of chemical flask test-tube symbol appears on the Activity Bar). Hovering over any row shows a "Play" symbol which triggers the run of the given test suite. Alternatively, you can run multiple tests in parallel by clicking the triangle icon on their parent row:

Docblocks in PHP

The neilbrayfield.php-docblocker (32K installs) is a highly configurable extension for auto-completing comment blocks containing documentation (called "docblocks" for short). Although it offers numerous configuration options to fine-tune the result being inserted when invoked, no combination has been found yet to 100% match the coding standards Drupal expects. As you can see in the screenshot below, you will need to manually break into a new line the descriptions of function @parameters and @return:

Besides this minor annoyance, it's a helpful addition for those writing a significant amount of PHP from scratch.

When working with PHP, Docblocker conflicts with the similar autocompletion feature of Devsense's PHP Tools extension (see above ). If you plan to install both extensions, it's recommended that you disable the latter.

Composer

The DEVSENSE.composer-php-vscode extension (part of the PHP Tools bundle) adds the following assistance when the composer.json file of the project is opened in an editor:

  1. Quick links to install, update, and check the external dependencies described in Composer's files.
  2. Hovering over a package name displays a balloon with key information about the package, including related links to jump to.
  3. Displays the exact version number installed, so you don't need to look it up from the lockfile manually.
  4. Autocomplete suggestions when manually editing the composer.json file. The IDE is aware of Composer's own JSON schema to apply here.
  5. Similarly, hovering over any valid top-level key briefly explains its purpose.

If you're not using the DEVSENSE.composer-php-vscode extension bundle for any reason, you should try a possible alternative. The ikappas.composer (353K installs) is an apparently abandoned extension (no new release for 3 years) and available only from Microsoft's marketplace, not from Open VSX Registry – thus cannot be installed in non-MS-made builds and forks of VS Code. Provide the path of the executable binary installed locally on the host computer:

# settings.json file

{
  ...
  // Mac & Linux
  "composer.executablePath": "/usr/local/bin/composer"
  // Windows
  "composer.executablePath": "C:\\ProgramData\\ComposerSetup\\bin\\composer.bat"
  ...
}

JavaScript

As stated in this guide's introduction, the VS Code builds and forks provide only limited support for PHP as a backend technology out of the box. This is because this IDE platform targets the developer audience primarily working with frontend-related languages like JavaScript, TypeScript, CSS, HTML, etc. In other words, if you are a Drupal themer or a React/Vue developer working with Drupal in decoupled architecture, you will probably find way more settings options, extensions available, and other solutions for your needs than the PHP folks.

However, after we have covered the configuration of the tools required for backend development, let's look at some extensions recommended for working with the JavaScript part of Drupal's codebase. 

Linting & fixing

To have a stable understanding of the background of utility tools used for frontend development in Drupal, it is strongly recommended to (at least) skim through the related documentation page.

Now, let's return to our project to continue setting up the IDE. First, it's important to note that, despite VS Codium's more integrated support of JavaScript (compared to PHP), it does not provide a linter tool out of the box. Therefore, you may want to install the dbaeumer/vscode-eslint (1,7M installs) extension from the marketplace. Once you follow the guide to set up the linter & fixer tooling on your local stack, this IDE extension automatically picks up its configuration. It starts reporting coding standard violations in the currently opened files, plus offering quick fixes where applicable:

VS Codium comes with a factory default formatter for JavaScript/ECMAScript files. Still, you can follow Drupal's coding standards for JS more strictly by replacing that with this ESLint integration extension set as the default formatter for such source code files:

# settings.json file

{
  "eslint.format.enable": true,
  "[javascript]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  }
}

If code linting does not initiate automatically, you may want to start troubleshooting by checking that all three of these settings have their factory default "true" values set: javascript.validate.enable, javascript.format.enable, and eslint.enable. As you can see, the ruleset we rely on from Prettier is already aggregated by ESLint, so there's no heavy reason to install the dedicated esbenp.prettier-vscode (2,2M) extension to your IDE – it barely adds extra functionality, but you can give a try, if you wish.

Debugging

Nowadays, all modern web browsers' DevTools panel offers functionality for stepping through a JavaScript file of a website once it has been loaded and is currently executed. However, if you want to check it in the broader context of a fully-fledged IDE, then the good news is that VS Codium offers built-in support for debugging JavaScript (in contrast with linting & fixing), thus setting up this functionality can be much easier. For the sake of simplicity, this guide focuses on the globally most popular web browser, Google Chrome (plus its forks and variants). Still, if you wish, you may want to go with the firefox-devtools.vscode-firefox-debug (77K) extension instead (not tested by the authors of this guide).

The software provides several ways to set up launching configurations, but probably the easiest is the following:

  1. Open the list of launch options.

    Decide on which level of IDE settings you want to create the new launch definition:

    • Workspace means it will live on your machine only
    • The project name in parentheses means it will be added to the launch.json file in the .vscode/ directory of your project codebase (thus can be shared with teammates). Choose this one for now.
  2. The structure schema of this kind of file automatically offers templates to fill in the newly added definition. Choose "Chrome: Launch".
  3. Give an arbitrary name to appear in the option list.
  4. Fill in the complete domain of your local website.

(If you have followed this guide from the beginning till this point, you should already have such a launch.json file – remember the section  above discussing Xdebug setup).

After saving the launch definition, your IDE is ready to step through Drupal's JavaScript files.

  1. Open the Command Palette, run the "Run and Debug: Focus on Breakpoints View" command, and mark both checkboxes with labels about catching exceptions.
  2. Choose your newly created launch option from the drop-down list, then hit the green "Play" button (with triangle icon).

A standalone window of Google Chrome should open up (see the lower right corner of the following screenshot), in the middle of loading the front page of your local website. If there are any (un)caught exceptions in the JavaScript codebase running (which is the usual case), the Debugger should halt at the point where it occurs:

As you can see, this is a minified JavaScript file: optimized for transmission but impossible for humans to read. Drupal has a built-in feature of aggregating frontend assets (CSS and JS files), which we need to temporarily disable. If you already have a settings.local.php file configured for your sandbox site, add this line to its end:

# Snippet from the `web/sites/default/settings.local.php` file.

$config['system.performance']['js']['preprocess'] = FALSE;

Alternatively, from the command line you can run $ ddev drush cset system.performance js.preprocess 0. Flushing caches: ddev drush cr, or even restarting the stack, might also be necessary for this setting to take effect. Reloading a page on a regular browser tab now should result in loading Drupal's various JavaScript files with the page. Choose any of these files you see that are loaded, copy its relative path, open it up in the IDE, then place a breakpoint somewhere. For example, in the attachBehaviors() function of the web/core/misc/drupal.js file. Now you can deactivate the checkboxes for exception catching.

When you click the green "Play" button again, the process should now pause at the breakpoint of your choice.

Pro Tip:
Debugger successfully halted on an exception, but not on the breakpoint? One common issue is the misconfiguration of the docroot directory in the launch.json file. If your project's codebase uses a non-standard docroot name, double-check if you have set it correctly.

Separating scopes

VS Codium offer a feature to declare separate contexts for JavaScript within the same project codebase. Read about how to define such jsconfig.json files in the official documentation. To properly configure IntelliSense you can install all the packages in the core's package.json  and add a jsconfig.json in your project's root directory, with the following content:

{
  "compilerOptions": {
    "module": "CommonJS",
    "target": "ES6"
  },
  "include": [
    "web/core/misc"
  ]
}

This way, IntelliSense will additionally pickup on all the JavaScript files included in Core.

Twig

The templating language Drupal utilizes also suffers the lack of built-in support from the IDE, but fortunately the necessary extensions can be found on the marketplace. Sorting the half-dozen relevant extensions by installation numbers, a vast gap shows between the two published by Matthew Blode (together counting thousands of downloads) and the rest of the others mentioning Twig in their names.

The most feature-complete extension, mblode.twig-language-2 (36K installs) has the version number "2" in its name because it's a fully independent rewrite of its v1 sibling (built from two different repositories on GitHub). If you wish, you can configure the IDE's built-in HTML parser (called Emmet) to assist you with completion suggestions for Twig files too:

# settings.json file

{
  ...
  "emmet.includeLanguages": {
    "twig": "html"
  },
  ...
}

Twig Linting

There are two Twig linter-fixer tools competing on the market: VincentLanglet/Twig-CS-Fixer and friendsoftwig/twigcs. In their README documentation, both refer to the single ruleset known, the official one published by the Symphony team behind the Twig templating system.

The latter one has integration with VS Codium: cerzat43.twigcs (662 installs) requires having the twigcs binary installed on your project's codebase (run $ ddev composer require --dev friendsoftwig/twigcs). The only minor inconvenience is that this extension does not autodetect the location of the required executable, so we need to inform it about its location manually:

# settings.json file

{
  ...
  "twigcs.executablePath": "vendor/bin/twigcs"
  ...
}

Once everything is set up, the Problems panel should show issues, if any:

Markup languages

Near the end of our guide, after setting up both programming languages (PHP and JavaScript), let's look at the three markup languages mainly used when working with Drupal.

JSON

Out of the box, VS Codium and other builds/forks provide quite decent support for JavaScript Object Notation (JSON) format: syntax highlighting, bracket matching, section folding, quick navigation based on the file structure tree, etc. More importantly, IntelliSense can validate their file content against any "JSON Schema" standard available on the schemastore․org. (Remember when you manually edited the IDE's settings.json file.) You can read more about its factory default functionality in the official documentation. Usually, these features should be enough for most Drupal developers, and we haven't heard of any additional extensions that are necessary or recommended to mention here.

YAML

Searching the marketplace shows the redhat.vscode-yaml (1,5M installs) extension is the most installed tool to support working with such files. It smoothly integrates file content validation based on JSON Schema standards. Drupal has over a dozen schemas defined for its various *.yml files. This extension always assigns the correct schema standard when editing your module's *.info.yml file or defining a new recipe, for example.

Markdown

Fortunately, Markdown support is similarly in a good position: narrowing the extension list by the "@builtin markdown" filters should show the factory default vscode.markdown-language-features, and (possibly) vscode.markdown extensions (the latter only when using a derivative build/fork IDE). Make sure that these two are enabled. Feel free to disable vscode.markdown-math if you do not plan to use KaTeX. Read more about Markdown support in the official documentation.

Drupal

By now your IDE should be ready to efficiently work with either the backend or the frontend of a website based on the latest major version of Drupal. All extensions we have downloaded, installed, and configured till now are generally available development tools, often used by fellows working on other PHP-driven CMS projects too.

However, the marketplace offers some Drupal-specific extensions worth briefly looking at. In the order of their installation count:

  1. andrewdavidblum.drupal-smart-snippets (13K installs)

    Probably the most helpful extension in this section: start type "hook…", followed by its name, then simply choose from the list, then hit Tab. The complete boilerplate snippet gets inserted, optionally picks up the name of your custom module, and then the cursor jumps over to the next editable part of the function signature.

    Only local images are allowed.

    The only caveat is that it conflicts with Devsense's PHP Tools. When both extensions are enabled, the snippet insertion feature of this extension loses its "intelligence", downgrading to simple code completion.

  2.  drupal-mentoring.drupalpod-ext (7,7K installs)
    As its README documentation states,

    "[it] should be installed automatically by GitPod"

    (which is an automated hosted solution), thus it's not something you need in your local development environment.

  3. skippednote.VS-code-drupal (4,5K installs)
    This admittedly simple extension only adds some extra settings to your project: it maps some Drupal-specific file name extensions with the proper file types the IDE handles. The decision is totally up to you whether you prefer to install one more extension to your IDE or manually copy over the following configuration:
    # settings.json file
    
    {
      ...
      "files.associations": {
        "*.php": "php",
        "*.engine": "php",
        "*.theme": "php",
        "*.install": "php",
        "*.inc": "php",
        "*.make": "php",
        "*.module": "php",
        "*.profile": "php",
        "*.test": "php",
        "*.info": "ini",
      },
      ...
    }
  4. nadim-vscode.twig-code-snippets (3,4K installs)
    Promises code snippets for Twig files of several PHP frameworks, among which supporting Drupal is the least mature based on the README docs. Seems abandoned: quite old (2 years since the last release), its repository is not available on GitHub, so did not manage to make it work by reading its source code.
     
  5. davis-are.drupal-sdc-helper (443 installs)
    Last but not least, an extension to support a relatively new technique in Drupal's universe, the Single Directory Components (SDC). Probably a must-have addition for frontend developers working with modern Drupal themes.

Abandoned extensions

You might stumble upon mentions of the following Drupal-related extensions in some older documentation. They seem deprecated (no new version has been released for many years), but let's mention them here for historical reference. Unfortunately, they are not available in the Open VSX Registry either.

  • Stanislav.vscode-drupal
  • dssiqueira.drupal-8-snippets
  • tsega.drupal-8-javascript-snippets
  • tsega.drupal-8-twig-snippets

Summary — Putting all together

If you have landed here by rushing on the fast track, welcome! Otherwise, your perseverance is highly appreciated if you have followed this guide from the beginning. Dozens of extensions were mentioned together with their many setting options, so finally it's time to condense them into a compact list for a quick installation and setup.

Before continuing, a solid understanding of VS Codium's cascaded configuration is needed. Check out the official documentation to make sense of the decreasing scope of settings options between User, Workspace, and Codebase levels.

Setting up individually

  1. First, augment the IDE with the necessary software components: download the attached extensions.json_.txt file with the following content, and save it to the .vscode/extensions.json path of your project codebase.
    {
      "recommendations": [
        "andrewdavidblum.drupal-smart-snippets",
        "biati.ddev-manager",
        "cerzat43.twigcs",
        "dbaeumer.vscode-eslint",
        "dbcode.dbcode",
        "devsense.composer-php-vscode",
        "devsense.phptools-vscode",
        "editorconfig.editorconfig",
        "mblode.twig-language-2",
        "neilbrayfield.php-docblocker",
        "sanderronde.phpstan-vscode",
        "valeryanm.vscode-phpsab"
      ]
    }
    
  2. Download the attached example.code-workspace.jsonc_.txt file, save it somewhere on your computer. Depending on your OS, you can place it among the other *.code-workspace files wherever VS Codium saves them.
  3. Rename it by removing the "_.txt" file name extension (necessary only to trick Drupal․org's file upload protection).
  4. Open this *.jsonc (JSON with Comments) file in any editor. Search through the entire document for occurrences of "// @todo". These are points where your action is required. Follow their instructions when filling in your missing values.
  5. When finished, rename the last remaining file name extension (".jsonc") too. Probably you want to rename the file from "example" to the name of your project.
  6. If your OS properly assigns *.code-workspace files to VS Codium, then double-click the file to open the IDE. Once it recognizes the list of recommended extensions, it automatically offers to install them.
  7. Some reported that this bulk installation process does not always get finished properly. Therefore, another option is to open the Command Palette, choose the "Extensions: Focus on Recommended View" option, and start manually clicking through the listed extensions. You might need to affirm your trust in the extension vendor when prompted.
  8. Run $ ddev composer require --dev friendsoftwig/twigcs if you plan to lint Twig files (see this section ↑).
  9. Smoke test that all features work as expected.

Note: the list of settings recommended here is limited to the ones where an override value is necessary. It does not contain all the other extension settings whose default value is good to go.

Share IDE settings with your team

If you work in a team where others use VS Codium or another build/fork, you can share the customized *.code-workspace file by committing it to version control. A good place to store it is in the .vscode directory, since the IDE ignores any extra files in that folder that are outside its scope. This way, anyone with read access to the repository can quickly launch their IDE, which is already configured for the project’s specific requirements. It’s not recommended to copy the *.code-workspace file out of the version-controlled directory, since any future updates to the file won’t be reflected in the local copy.

Pro Tip:
Your project doesn't need separate launch.json, tasks.json, or settings.json files in the .vscode/ directory if all their content is already incorporated into this single workspace file.

Useful settings as personal globals

# settings.json file in your OS user home.

{
  "diffEditor.ignoreTrimWhitespace": false,
  "editor.formatOnPaste": true,
  "editor.renderWhitespace": "boundary",
  "files.trimTrailingWhitespace": true,
  "files.insertFinalNewline": true,
  "telemetry.telemetryLevel": "off",
}

Additional useful extensions

These were the baseline functionalities that most developers usually need to use. However, if you wish to customize your development experience even further, keep reading and scan through the following list of other extensions that other Drupalists have found helpful during their everyday work.

mehedidracula.php-namespace-resolver (23K installs)
Some recommends its features, but Devsense's PHP Tools also includes its functionality.

alefragnani.numbered-bookmarks (1,5K installs)
Provides the well-known bookmarking functionality as it works in other IDEs. You need to add this line to your settings.json file to guarantee every numbered bookmark can occur only once:

{
  "numberedBookmarks.navigateThroughAllFiles": "replace"
}

sketchbuch.vsc-workspace-sidebar (2,7K installs)
If you are working on many projects in parallel and frequently hopping between them (eg. working at a Drupalshop), then this extension makes switching IDE workspaces easier with a single click.

HaaLeo.timing (2,7K installs)
Hovering over any UNIX epoch timestamp (eg. in log files) or using an option from the Command Palette to convert an input string to a properly formatted time string.

CucumberOpen/cucumber-official (41K installs)
Provides syntax highlighting and other useful functionalities to work with *.feature files (usually used for Behat tests).

Even more extensions to consider:

License

The IDE may have a different license depending on the means of distribution. The installable "VS Code" product offered by Microsoft is compiled with additional configuration and software under the proprietary Microsoft Software License. However, its base source code is licensed under the MIT License. Therefore, derivative software products are available built upon its codebase. See them listed in the Overview section of this guide.

Help improve this page

Page status: No known problems

You can: