Working with regions in VSCode
Master code folding in VSCode with regions. Learn how to use them in PHP and how to enable region support for unsupported files like Dockerfile with a simple extension.
This article is over a year old but was reviewed on July 30, 2026 — the content is still accurate.
This article is part of the VSCode - Tips, extensions and shortcuts series:
- Markdown folding not working
- Start vscode from github.com
- Sticky scroll in vscode
- Autosave feature in VSCode
- Error Lens addon for VSCode
- CodeSnap addon for VSCode
- Export the list of extensions you've installed in VSCode
- Multiple cursors in vscode
- PHP Getter and Setter in VSCode
- Working with regions in VSCode
- Using the JetBrains Mono font in vscode
- Todo Tree in VSCode
- Do I need VSCode on my machine to use it?

This article shows how to use region/endregion folding tags in VSCode (e.g. in PHP) to collapse logical blocks of code, and how to add that same folding support to files VSCode doesn't handle natively, like a Dockerfile, using the maptz.regionfolder extension plus a .vscode/settings.json entry. It also mentions the Auto Fold extension for automatically collapsing regions when a file is opened.
VSCode supports region and endregion tags but not everywhere. These two special tags can be written differently depending on the language you're using but always have the same objective: to allow you to fold part of the code.
Not everywhere means, for instance, that VSCode doesn't support code folding by default in a Dockerfile. Let's see how to solve this.
A well-folded file is one thing; a well-organized one is another. For Bash, Linux - Sort functions in a Bash script checks that your functions are declared in a predictable order.
Regions in action

That's what region/endregion tags buy you: entire logical blocks collapse to a single line,
so you see the structure of a file instead of scrolling through it.
Code folding in PHP
Consider the following, very basic, example (very brief example for illustrative purposes):
<?php
class MyClass{ public function onContentPrepare() { $query = $this->db->getQuery(true); $query->select('note'); $query->from('#__content_ratings'); $query->where('content_id = 8');
$this->db->setQuery($query); $notes = $this->db->loadColumn();
return $notes; }}This class method queries a database table to retrieve notes associated with a specific piece of content. It builds a SQL query to fetch the 'note' column from the ratings table where the content ID is 8, executes the query, and returns all the results as an array.
We can clearly identify three blocks: preparation of the query, run it and return the data. Using regions, we can do this — the two lines shown above (// #region, // #endregion) are what produce the fold/unfold behavior in the gif:
<?php
class MyClass{ public function onContentPrepare() { //region 1. Prepare the SQL query $query = $this->db->getQuery(true); $query->select('note'); $query->from('#__content_ratings'); $query->where('content_id = 8'); //endregion
//region 2. Run the query $this->db->setQuery($query); $notes = $this->db->loadColumn(); //endregion
//region 3. Prepare resulting array return $notes; //endregion }}This method builds and executes a database query to fetch all 'note' values from a ratings table where the content ID matches 8, then returns those notes as an array. It's a straightforward data retrieval operation that abstracts the database interaction into a single reusable function.
You should avoid having functions having more than 60 lines
Regions are supported by a very large number of languages, but don't make the mistake of assuming that this allows you to have functions of several dozen lines. That's not the point! If you have long functions, you need to split them up. You need to create smaller, more specialised functions. We've already touched on this point in a previous post.
What to do when VSCode didn't support these tags by default?
Let's take a look and the following Dockerfile:
# syntax=docker/dockerfile:1
# Source https://docusaurus.community/knowledge/deployment/docker/?package-managers=yarn
ARG HOMEDIR=/opt/docusaurusARG TARGET=/development
# The user and group ID of the user to createARG DOCKER_UID=1000ARG DOCKER_GID=1000ARG USERNAME=christophe
# Stage 1: Base image.
FROM node:lts AS base
# Disable color output from yarn to make logs easier to read.ENV FORCE_COLOR=0
# Enable corepack.RUN corepack enable
ARG TARGETRUN /bin/bash -c "echo \"PS1='\n\e[0;33m🐳 (${TARGET})\e[0m - \e[0;36m$(whoami)\e[0m \w # '\" >> ~/.bashrc "
# --------------------------------------------------------------------
# Stage 2a: Development mode.
FROM base AS development
ARG HOMEDIR
RUN apt-get -y update \ && apt-get install --yes --no-install-recommends git \ && git config --global --add safe.directory ${HOMEDIR} \ && rm -rf /var/lib/apt/lists/*
# We'll create a new user with the same uid/gid than ours, on our host machine.ARG DOCKER_UIDARG DOCKER_GIDARG USERNAME
# hadolint ignore=DL3008RUN set -e -x \ && if [ ! "$DOCKER_UID" = "1000" ]; then \ groupadd --gid ${DOCKER_GID} "${USERNAME}" \ && useradd --home-dir /home/"${USERNAME}" --create-home --uid ${DOCKER_UID} \ --gid ${DOCKER_GID} --shell /bin/sh --skel /dev/null "${USERNAME}" ; \ fi
USER "${USERNAME}"
# Set the working directory to `/opt/docusaurus`.WORKDIR "${HOMEDIR}"
# --------------------------------------------------------------------
# Stage 2b: Production build mode.
FROM base AS building_production
ARG TARGET
# Target is set in the .env file to "development" or "production"ENV NODE_ENV="${TARGET}"
# Install the latest version of DocusaurusARG HOMEDIRRUN npx create-docusaurus@latest "${HOMEDIR}/" classic --javascript \ # Remove dummy files like dummy blog, docs, ... that were added during the installation && rm -rf "${HOMEDIR}/blog" "${HOMEDIR}/docs" "${HOMEDIR}/src" \ && chown -R node:node "${HOMEDIR}/"
# Set the working directory to `/opt/docusaurus`.WORKDIR "${HOMEDIR}"
# We need our package.json / package.lock file before running yarn installCOPY package.* .
# Install dependencies with `--immutable` to ensure reproducibility.RUN yarn install --immutable
# Copy over the source code.COPY . "${HOMEDIR}/"
# Build the static site (generated files will be created in /opt/docusaurus/build)RUN yarn build
# --------------------------------------------------------------------
# Stage 3: Serve with nginx
FROM nginx:stable-alpine3.19-perl AS production
RUN set -e -x; \ apk update --no-cache && apk add --no-cache bash \ && rm -rf /var/cache/apk/*
ARG TARGET
RUN /bin/sh -c "echo \"PS1='\n\e[0;33m🐳 (${TARGET})\e[0m - \e[0;36m$(whoami)\e[0m \w # '\" >> ~/.bashrc "
# Copy the Docusaurus build output.ARG HOMEDIR
COPY --from=building_production "${HOMEDIR}/build /usr/share/nginx/html"
WORKDIR /usr/share/nginx/htmlThis Dockerfile creates a Docker image for a Docusaurus website with three stages: a base Node.js image with common setup, a development stage where a user can work on the site, and a production stage that builds the site and serves it through nginx. The file uses build arguments to customize the user ID, group ID, and username for development work, and to control whether the image targets development or production environments.
Opening such a file in VSCode doesn't provide any collapse/expand features and we will need to scroll a lot. And we don't have a global overview of the structure.

The solution comes by installing a specialised extension: https://marketplace.visualstudio.com/items?itemName=maptz.regionfolder.
And, too, by adding these settings in your .vscode/settings.json file:
{ "maptz.regionfolder": { "[dockerfile]": { "foldEnd": "\\# endregion", "foldEndRegex": "\\# endregion[\\s]*(.*)$", "foldStart": "\\# region [NAME],", "foldStartRegex": "\\# region[\\s]*(.*)$" } }}This is a configuration object for a VS Code extension called 'maptz.regionfolder' that teaches the editor how to recognize and fold code regions in Dockerfile files. It defines the text markers (comments) that indicate where a foldable region starts and ends, along with regex patterns to find those markers.
Switch back to your tab in VSCode with your opened Dockerfile, press CTRL+P and run Developer: Reload Window to reload the window once the extension has been enabled and tadaaa!

No, it's not just a visual trick
When you're working on very long files like, for me, a Dockerfile of over 900 lines, it's really imperative to be able to have regions that you can reduce/expand.
Not only does this make it easier to read, it also facilitates the succession of 'stages' (when programming a multistage Dockerfile).
Auto fold extension
There are some extensions like Auto Fold that can automatically fold regions when opening a file.
The idea is: when you open a file with a lot of methods, all functions are first folded (we just see the function name, not its content). That way you can directly see the structure of the file, the list of functions and so on without having to scroll much.
If you install Auto Fold, you also need to add the "autofold.default": 1, setting in your settings.json file.
If you don't know how, just press CTRL+, (the comma) to display the Settings page then start to type autofold to get access to the setting.
Now, if you open a file, its content will be automatically folded.
Conclusion
Two tags, // #region and // #endregion (adapted to your language's comment syntax), are all
it takes to fold any block of code — native in most languages, and easy to bolt onto the ones
VSCode doesn't support out of the box, like a Dockerfile.
This article is part of the VSCode - Tips, extensions and shortcuts series:
- Markdown folding not working
- Start vscode from github.com
- Sticky scroll in vscode
- Autosave feature in VSCode
- Error Lens addon for VSCode
- CodeSnap addon for VSCode
- Export the list of extensions you've installed in VSCode
- Multiple cursors in vscode
- PHP Getter and Setter in VSCode
- Working with regions in VSCode
- Using the JetBrains Mono font in vscode
- Todo Tree in VSCode
- Do I need VSCode on my machine to use it?





