Open-source project
tgjones/HlslTools avatar
tgjones/HlslTools

HLSL Tools: a real parser and preprocessor for HLSL in Visual Studio

A Visual Studio extension that provides enhanced support for editing High Level Shading Language (HLSL) files

636 stars106 forksHLSLNOASSERTION

At a glance

What is it?
HLSL Tools is a Visual Studio 2019 and 2022 extension that gives shader code IntelliSense, live errors, go to definition and preprocessor awareness, backed by a handwritten HLSL parser rather than a generated one. It also has a Visual Studio Code counterpart, and it stopped receiving pushes on 2026-04-09.
Who is it for?
Adopt HLSL Tools if you edit HLSL inside Visual Studio 2019 or 2022 and want the code navigation, live diagnostics and preprocessor awareness that the built-in HLSL support does not provide, and if you are willing to work with an extension that has not been pushed to since 2026-04-09. Do not adopt it if your shaders are edited in Visual Studio Code, where the project ships a separate extension, or if your editor is not Visual Studio at all.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly HLSL, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Visual Studio already does, and what the extension adds

Since Visual Studio 2012, Visual Studio has shipped with basic support for editing HLSL files. The extension's argument is entirely about the difference between that basic support and a real language service, and the README lays it out as a table.

What Visual Studio already gives you is syntax highlighting, automatic formatting, brace matching, brace completion and outlining. On top of that, HLSL Tools adds statement completion, signature help, reference highlighting, a navigation bar, Navigate To, live errors, go to definition, quick info, graying out of code excluded by the preprocessor, and HLSL-specific preferences.

The last item is the one that most often gets overlooked and it is the one that decides whether the tool is usable for you. IntelliSense in HLSL is only as good as the compilation environment it thinks it is in, and the extension therefore lets you configure HLSL-specific IntelliSense and formatting options, with the option to disable IntelliSense entirely and keep only the other features. You can also set HLSL-specific highlighting colours under Tools, Options, Environment, Fonts and Colors.

The navigation features are the ones that change how you work in a large shader codebase. Navigate To with Ctrl+, finds a variable, function or other symbol by name. Go to definition works for variables, fields, functions, classes, macros and more, on F12. Reference highlighting marks every reference to the symbol under the cursor, and you move between them with Ctrl+Shift+Up and Ctrl+Shift+Down. Quick info gives a tooltip on hover over almost anything, including a macro, a semantic or a type.

The README also notes there are more features on the roadmap, tracked in the changelog.

Live errors and the completion machinery behind them

Live errors are the feature that changes the character of the tool. HLSL Tools shows syntax and semantic errors immediately, with no need to wait for compilation, and they appear as squigglies and in the error list.

The reason this is possible is the parser, and the parser is the interesting engineering decision in the project. HLSL Tools includes a handwritten HLSL parser. It initially used an ANTLR lexer and parser, but the handwritten version was faster, and offered better error recovery.

Error recovery is the property that matters most for an editor, and it is worth being precise about what it means. A generated parser typically bails on the first syntax error and everything after it is unparseable, so a single missing semicolon produces a cascade of nonsense diagnostics. A handwritten parser can resynchronise, keep going, and report the one real problem. For a language with preprocessor directives, macros and a lot of half-written code in the editor at any moment, that difference is the difference between a usable live error list and a useless one.

Statement completion is the counterpart. You start typing and HLSL Tools shows the symbols available at that location, and you can trigger it manually with the usual shortcuts, Ctrl+J and Ctrl+Space among them. Signature help shows all the overloads for a function call along with information from MSDN about the function, its parameters and its return types, and it is available for all HLSL functions and methods, including the older tex2D-style texture sampling functions and the newer Texture2D.Sample-style methods.

Typing an open parenthesis triggers it, as does the standard Ctrl+Shift+Space shortcut. Note the dependency on MSDN for the documentation content, which is a detail worth knowing before you rely on it offline.

The preprocessor is the part that has to be right

HLSL Tools evaluates preprocessor directives as it parses your code and grays out the excluded code. When you want a code block to be visible to, or hidden from, the tool, you use the __INTELLISENSE__ macro, which is the mechanism for controlling what the language service sees independently of what the compiler sees.

Underneath, there is a built-in preprocessor that handles the #define and #include directives, and its behaviour is customised through a file named shadertoolsconfig.json:

json
{
  "hlsl.preprocessorDefinitions": {
    "MY_PREPROCESSOR_DEFINE_1": "Foo",
    "MY_PREPROCESSOR_DEFINE_2": 1
  },
  "hlsl.additionalIncludeDirectories": [
    "C:\\Code\\MyDirectoryA",
    "C:\\Code\\MyDirectoryB",
    ".",
    "..\\RelativeDirectory"
  ],
  "hlsl.virtualDirectoryMappings": {
    "/Project": "C:\\MyProject\\Shaders"
  }
}

The three keys each solve a specific problem. hlsl.preprocessorDefinitions exists because additional defines are normally part of a project build, and in some cases the shader will not compile correctly without them, so you add them here as well. hlsl.additionalIncludeDirectories exists because by default the tool only uses the directory containing the source file to search for #include files. hlsl.virtualDirectoryMappings configures the virtual directory mappings, which the documentation ties to Unreal's requirements.

This is the point where a project usually goes wrong. If the extension does not know about the same defines the build uses, it parses a different program from the one you are compiling, and the live errors it reports are errors in a program that does not exist. Diagnosing that mismatch is much harder than a compile error, because the tool is usually right about the syntax and wrong about the configuration.

Testing against the SDK shader corpora

The project is candid about its test coverage, and the candour is useful. The README says HLSL Tools has a reasonable test suite, although it can certainly be improved.

Among more granular tests, it includes a suite of 433 shaders, including all of the shaders from the DirectX and Nvidia SDKs. That is the right shape of test for a parser, and it explains the decision to hand-write it. A grammar-based parser can be tested on the language definition, but a hand-written parser that must survive incomplete and erroneous code is only trustworthy if it is run against a large body of real shaders, and the SDK shader sets are exactly that.

The repository also asks for help with the hard cases. If you want to contribute gnarly source files which push HLSL to its limit, that would be great, which tells you that the maintainer agrees the corpus is where the remaining risk lives. A parser that handles the SDK shaders is not the same as a parser that handles whatever your engine's shader library contains.

The repository layout supports that kind of testing work: there is a scripts/ directory, a tools/ directory, a build.cmd for Windows builds, an appveyor.yml and an azure-pipelines.yml for continuous integration, and the build badge points at an Azure Pipelines definition. There is a .github/ directory and a CONTRIBUTING.md, so the project is set up for outside contributions.

A syntax visualizer, and a second editor

Two smaller features are worth knowing about because they tell you what kind of project this is.

The syntax visualizer is inspired by Roslyn and shows the parse tree of a shader. The README is honest that it is primarily of interest to HLSL Tools developers, and that it may be of interest to language nerds, and it is included in the main extension anyway. You open it from View, then Other Windows, then HLSL Syntax Visualizer. A parse tree viewer is a debugging aid for the parser itself, and shipping it in the user-facing package is a small decision that costs some surface area and saves anyone trying to understand the parser's behaviour from error messages.

The second thing is that this is not a Visual Studio only project. The README states at the top that the extension is for Visual Studio 2019 and 2022 and points to a separate location in the same repository for the Visual Studio Code extension. That is worth noting when you evaluate the project, because the two extensions share the parser and the preprocessor, and improvements to the analysis engine benefit both.

The distribution route is the Visual Studio Marketplace, and the download link in the README points there. The build status badge points at Azure Pipelines on the master branch, and the project has no GitHub releases, so the version history is the changelog file and the marketplace listing.

Where HLSL Tools is the wrong choice

The first limitation is the extension host, and it is not a small one. This is a Visual Studio extension, so it only helps if you edit shaders in Visual Studio 2019 or 2022. A team that has moved to Visual Studio Code, or to Rider, or to a mixed editor situation, gets nothing from this package and needs the separate Code extension or a different tool entirely. The same applies to any editor outside the Visual Studio family, and no amount of parser quality changes that.

The second limitation is the assumption of a Windows toolchain. The preprocessor configuration example uses Windows paths, the build script is build.cmd, and the CI configuration includes appveyor.yml alongside azure-pipelines.yml. The virtual directory mappings exist to satisfy Unreal's requirements, which is a Windows-centric toolchain. A team on Linux with a build system that defines its shader macros elsewhere will find the configuration awkward to express.

The third limitation is the dependency on external documentation for signature help, since the function information comes from MSDN. That is a network dependency inside an editor feature, and it is a real one in a locked-down environment.

The real alternative is the pair of things Visual Studio already gives you and the engine toolchain. The built-in HLSL support in Visual Studio has been there since 2012 and covers the basics, and if your needs are limited to highlighting and formatting, that is the answer with no extension and no configuration. Beyond that, the real alternative is the shader tooling that ships with your engine or your build system, a DirectX Shader Compiler wrapper, or a clangd-based setup, which bring their own knowledge of your project structure, your include paths and your define set because they are configured from the same place as the build. The difference in approach is that HLSL Tools reconstructs a plausible compilation environment from a configuration file you write, while engine-integrated tooling reads the real one. That makes HLSL Tools the better answer when your shader build lives outside the IDE and the IDE knows nothing about it, and the worse answer when your build system is already integrated with your editor, because you would then be maintaining the same information twice.

Editorial conclusion

Adopt HLSL Tools if you edit HLSL inside Visual Studio 2019 or 2022 and want the code navigation, live diagnostics and preprocessor awareness that the built-in HLSL support does not provide, and if you are willing to work with an extension that has not been pushed to since 2026-04-09. Do not adopt it if your shaders are edited in Visual Studio Code, where the project ships a separate extension, or if your editor is not Visual Studio at all. Before you install it, check that your build defines the same preprocessor symbols the extension is told about in shadertoolsconfig.json, because a mismatch there produces the false live errors the tool is meant to prevent, and read the changelog for the version history since the repository publishes no releases.

Frequently asked questions

What is HLSL Tools?

It is a Visual Studio 2019 and 2022 extension that provides enhanced support for editing HLSL files, adding statement completion, signature help, reference highlighting, a navigation bar, Navigate To, live errors, go to definition, quick info and preprocessor awareness on top of the basic HLSL support Visual Studio has shipped since 2012.

How do I install HLSL Tools?

The extension is downloaded from the Visual Studio Marketplace, and the README links that listing directly. A separate Visual Studio Code extension lives in the same repository under a different path in the source tree, and the project publishes no GitHub releases, so the marketplace listing and the changelog are the version history.

What is shadertoolsconfig.json used for in HLSL Tools?

It customises the built-in preprocessor that handles #define and #include directives. The hlsl.preprocessorDefinitions key adds defines the project build uses, hlsl.additionalIncludeDirectories adds directories beyond the one holding the source file, and hlsl.virtualDirectoryMappings configures the virtual directory mappings required by Unreal.

How does HLSL Tools handle preprocessor directives and excluded code?

It evaluates preprocessor directives as it parses your code and grays out the code that is excluded, and the __INTELLISENSE__ macro lets you make a block visible to or hidden from the tool independently of the compiler. Matching the extension's definitions to the ones your build uses is what keeps the live errors meaningful.

Why does HLSL Tools use a handwritten parser instead of ANTLR?

The README says it initially used an ANTLR lexer and parser, but the handwritten version was faster and offered better error recovery, which is what makes live syntax and semantic errors usable in an editor. The test suite includes 433 shaders drawn from the DirectX and Nvidia SDKs, and the project asks for contributions of gnarly shader files that push HLSL to its limit.

Official sources

  1. Issues
  2. Project website
  3. README
  4. tgjones/HlslTools on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tgjones-hlsltools.svg)](https://hysenlabs.com/projects/tgjones-hlsltools)

Was this useful?