Syntax highlighting is broken.
Take a look at this example, from the configuration file of Laravel Octane.

Most of the classes are completely unstyled!
return [
    'listeners' => [
        WorkerStarting::class => [                                      ❌
            EnsureUploadedFilesAreValid::class,                         ❌
        ],

        RequestReceived::class => [                                     ❌
            ...Octane::prepareApplicationForNextOperation(),            ❌
            ...Octane::prepareApplicationForNextRequest(),              ❌
        ],

        WorkerErrorOccurred::class => [                                 ❌
            ReportException::class,                                     ❌
            StopWorkerIfNecessary::class,                               ❌
        ],
    ],

    'warm' => [
        ...Octane::defaultServicesToWarm(),                             ❌
    ],
]
Wrong
Blade templates are completely wrong.

Take a look at the last couple of lines. What's going on there?
@if (count($records) === 1)                                             ❌
    I have one record!
@elseif (count($records) > 1)                                           ❌
    I have {{ count($records) }} records!                               ❌
@else
    I don't have <span class='font-bold'>any</span> records!            ❌
@endif                                                                  ❌
Wrong
It misses most of this JavaScript content as well.
fs.readdirSync(path.join(process.cwd(), 'posts')).forEach(slug => {     ❌
    let content = fs.readFileSync(                                      ❌
        path.join(process.cwd(), 'posts', slug),                        ❌
        'utf-8'
    )

    fs.writeFileSync(                                                   ❌
        path.join(process.cwd(), 'build', `${slug}.html`),              ❌
        md.render(content)                                              ❌
    )                                                                   ❌
})                                                                      ❌
Wrong
Torchlight
is a syntax highlighting API powered by the Visual Studio Code engine.

It always gets it right, even for esoteric stuff.

Use any available VS Code theme, or make your own.

It supports every language VS Code supports, and any language you can find a tmLanguage.json file for.

It requires no JavaScript. Really. Torchlight is an API with server-side clients. Fully highlighted HTML is sent to the browser. No FOUC.

Let's take a look at those examples again.

Hightlight.js misses all the classes here.
return [
    'listeners' => [
        WorkerStarting::class => [                                      ❌
            EnsureUploadedFilesAreValid::class,                         ❌
        ],

        RequestReceived::class => [                                     ❌
            ...Octane::prepareApplicationForNextOperation(),            ❌
            ...Octane::prepareApplicationForNextRequest(),              ❌
        ],

        WorkerErrorOccurred::class => [                                 ❌
            ReportException::class,                                     ❌
            StopWorkerIfNecessary::class,                               ❌
        ],
    ],

    'warm' => [
        ...Octane::defaultServicesToWarm(),                             ❌
    ],
]
Torchlight correctly renders them all.
1return [
2 'listeners' => [
3 WorkerStarting::class => [
4 EnsureUploadedFilesAreValid::class,
5 ],
6
7 RequestReceived::class => [
8 ...Octane::prepareApplicationForNextOperation(),
9 ...Octane::prepareApplicationForNextRequest(),
10 ],
11
12 WorkerErrorOccurred::class => [
13 ReportException::class,
14 StopWorkerIfNecessary::class,
15 ],
16 ],
17
18 'warm' => [
19 ...Octane::defaultServicesToWarm(),
20 ],
21]
Highlight.js doesn't support Blade at all.
@if (count($records) === 1)                                             ❌
    I have one record!
@elseif (count($records) > 1)                                           ❌
    I have {{ count($records) }} records!                               ❌
@else
    I don't have <span class='font-bold'>any</span> records!            ❌
@endif                                                                  ❌
Torchlight gets the Blade, PHP, and HTML right.
1@if (count($records) === 1) ✅
2 I have one record!
3@elseif (count($records) > 1) ✅
4 I have {{ count($records) }} records! ✅
5@else
6 I don't have <span class='font-bold'>any</span> records! ✅
7@endif
Hightlight.js doesn't correctly pick up the JavaScript methods
fs.readdirSync(path.join(process.cwd(), 'posts')).forEach(slug => {     ❌
    let content = fs.readFileSync(                                      ❌
        path.join(process.cwd(), 'posts', slug),                        ❌
        'utf-8'
    )

    fs.writeFileSync(                                                   ❌
        path.join(process.cwd(), 'build', `${slug}.html`),              ❌
        md.render(content)                                              ❌
    )                                                                   ❌
})                                                                      ❌
Torchlight correctly picks them all up.
1fs.readdirSync(path.join(process.cwd(), 'posts')).forEach(slug => { ✅
2 let content = fs.readFileSync( ✅
3 path.join(process.cwd(), 'posts', slug), ✅
4 'utf-8'
5 )
6
7 fs.writeFileSync( ✅
8 path.join(process.cwd(), 'build', `${slug}.html`), ✅
9 md.render(content) ✅
10 ) ✅
11}) ✅

Getting the highlighting right is table-stakes.

Torchlight goes further by helping you communicate your ideas clearly.

Focus Your Reader's Attention
Quickly focus your reader's attention on the relevant portions of your code, while still giving the full context.
Hover over the block to bring the whole block into focus.
No JavaScript required! Just plain ol' CSS.
1<?php
2/**
3 * Chunk the collection into chunks of the given size.
4 *
5 * @param int $size
6 * @return static
7 */
8public function chunk($size)
9{
10 if ($size <= 0) {
11 return new static;
12 }
13
14 $chunks = [];
15
16 foreach (array_chunk($this->items, $size, true) as $chunk) {
17 $chunks[] = new static($chunk);
18 }
19
20 return new static($chunks);
21}
<?php
/**
 * Chunk the collection into chunks of the given size.
 *
 * @param int $size
 * @return static
 */
public function chunk($size)
{
    if ($size <= 0) {
        return new static;
    }

    $chunks = [];

    foreach (array_chunk($this->items, $size, true) as $chunk) { // [tl! **]
        $chunks[] = new static($chunk); // [tl! **]
    } // [tl! **]

    return new static($chunks);
}
Language: PHP. Theme: Github Dark
Clearly Visualize Differences Diffs
When explaining something in your docs or your blog posts, it's helpful to show your reader exactly what has changed.
1<?php
2/**
3 * Chunk the collection into chunks of the given size.
4 *
5 * @param int $size
6 * @return static
7 */
8public function chunk($size)
9{
10 if ($size <= 0) {
11 return new static;
12 }
13
14 $chunks = array();
15 $chunks = [];
16
17 foreach (array_chunk($this->items, $size, true) as $chunk) {
18 $chunks[] = new static($chunk);
19 }
20
21 return new static($chunks);
22}
<?php
/**
 * Chunk the collection into chunks of the given size.
 *
 * @param int $size
 * @return static
 */
public function chunk($size)
{
    if ($size <= 0) {
        return new static;
    }

    $chunks = array(); // [tl! --]
    $chunks = []; // [tl! ++]

    foreach (array_chunk($this->items, $size, true) as $chunk) {
        $chunks[] = new static($chunk);
    }

    return new static($chunks);
}
Language: PHP. Theme: Github Dark
Combine Diffing and Focusing
Combine both if you want, you have total control over how your code is presented.
Take a look at the source tab to see how easy it is to annotate your code.
1<?php
2/**
3 * Chunk the collection into chunks of the given size.
4 *
5 * @param int $size
6 * @return static
7 */
8public function chunk($size)
9{
10 if ($size <= 0) {
11 return new static;
12 }
13
14 $chunks = array();
15 $chunks = [];
16
17 foreach (array_chunk($this->items, $size, true) as $chunk) {
18 $chunks[] = new static($chunk);
19 }
20
21 return new static($chunks);
22}
<?php
/**
 * Chunk the collection into chunks of the given size.
 *
 * @param int $size
 * @return static
 */
public function chunk($size)
{
    if ($size <= 0) {
        return new static;
    }

    $chunks = array(); // [tl! -- **]
    $chunks = []; // [tl! ++ **]

    foreach (array_chunk($this->items, $size, true) as $chunk) {
        $chunks[] = new static($chunk);
    }

    return new static($chunks);
}
Language: PHP. Theme: Github Dark

Insanely Easy Installation

Torchlight is an API, with clients for popular backend languages. We currently have a vanilla Laravel client, a Laravel + Commonmark client, and we're working on a Rails + Commonmarker client!

To install, you only have to require the package by running composer require torchlight/laravel, and then publish the config via php artisan torchlight:install

If you're using league/commonmark, you just add the Torchlight extension and that's it!

1/*
2|--------------------------------------------------------------------------
3| CommonMark Extensions
4|--------------------------------------------------------------------------
5|
6| This option specifies what extensions will be automatically enabled.
7| Simply provide your extension class names here.
8|
9| Default: []
10|
11*/
12
13'extensions' => [
14 TorchlightExtension::class,
15],

Just using Blade views? You can use the Blade component!

1<x-code-torchlight language='php'>
2 // Any code here will be highlighted by Torchlight!
3</x-code-torchlight>
Psst... This page isn't done yet, I'm still working on it!
Do you have thoughts so far? I'd love to hear them. Hit me up on Twitter!
https://twitter.com/aarondfrancis.