diff --git a/.github/labeler.yml b/.github/labeler.yml
index 682cd347190466a711ff8c6d6dea679844e899f1..f7c548794ff9fb12d0286abf70483fc50dbe214f 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -134,6 +134,9 @@ lang-pony:
 lang-python:
   - lib/compilers/python.js
   - etc/config/python.*.properties
+lang-racket:
+  - lib/compilers/racket.ts
+  - etc/config/racket.*.properties
 lang-ruby:
   - lib/compilers/ruby.js
   - etc/config/ruby.*.properties
diff --git a/docs/AddingALanguage.md b/docs/AddingALanguage.md
index 6881ec6969f207324d3c33ea92386383f1f78703..02c763da400cd50b2fc2c692f01d5a7b023c7aed 100644
--- a/docs/AddingALanguage.md
+++ b/docs/AddingALanguage.md
@@ -19,7 +19,8 @@ If you want to add a new language to the site, you should follow this steps:
 
   - If the language is supported by Monaco Editor (You can find the list
     [here](https://github.com/microsoft/monaco-editor/tree/main/src/basic-languages)), you should add it to the list of
-    languages inside the `MonacoEditorWebpackPlugin` config in `webpack.config.js`
+    languages inside the `MonacoEditorWebpackPlugin` config in
+    `webpack.config.esm.js`
   - If not, you should implement your own language mode; see `static/modes/asm-mode.js` as an example. Don't forget to
     _require_ your mode file in `static/modes/_all.ts`, in alphabetical order
   - `language-key` is how your language will be referred internally by the code. In the rest of this document, replace
diff --git a/etc/config/racket.amazon.properties b/etc/config/racket.amazon.properties
new file mode 100644
index 0000000000000000000000000000000000000000..cead970ba171aea31bb4a4d573ac748725f5a2f4
--- /dev/null
+++ b/etc/config/racket.amazon.properties
@@ -0,0 +1,12 @@
+compilers=&racket
+defaultCompiler=racket86
+
+group.racket.groupName=Racket
+group.racket.compilers=racket86
+group.racket.isSemVer=true
+group.racket.baseName=Racket
+group.racket.licenseName=MIT and Apache 2
+group.racket.licenseLink=https://docs.racket-lang.org/license/
+compiler.racket86.semver=8.6
+compiler.racket86.exe=/opt/compiler-explorer/racket/racket-8.6/bin/racket
+compiler.racket86.raco=/opt/compiler-explorer/racket/racket-8.6/bin/raco
diff --git a/etc/config/racket.defaults.properties b/etc/config/racket.defaults.properties
new file mode 100644
index 0000000000000000000000000000000000000000..525cae32f56621a6a6da362e25989fad39966dd3
--- /dev/null
+++ b/etc/config/racket.defaults.properties
@@ -0,0 +1,13 @@
+compilers=racket
+compilerType=racket
+
+versionFlag=--version
+versionRe=Racket v\d+\.\d+(\.\d+)?
+
+interpreted=true
+supportsBinary=false
+supportsExecute=false
+
+compiler.racket.name=Racket
+compiler.racket.exe=/usr/local/bin/racket
+compiler.racket.raco=/usr/local/bin/raco
diff --git a/examples/racket/default.rkt b/examples/racket/default.rkt
new file mode 100644
index 0000000000000000000000000000000000000000..6a72e0d36a9497ee7c569b6ce07a6c77f63c3108
--- /dev/null
+++ b/examples/racket/default.rkt
@@ -0,0 +1,5 @@
+#lang racket/base
+
+;; Type your code here, or load an example.
+(define (square num)
+  (* num num))
diff --git a/lib/compilers/_all.js b/lib/compilers/_all.js
index 4056ecac74e230b7ef04ce3cee2c5c1899ab901d..fcd31fddac602f0c6a8dd835aca19a0646df832a 100644
--- a/lib/compilers/_all.js
+++ b/lib/compilers/_all.js
@@ -79,6 +79,7 @@ export {PonyCompiler} from './pony';
 export {PPCICompiler} from './ppci';
 export {PtxAssembler} from './ptxas';
 export {PythonCompiler} from './python';
+export {RacketCompiler} from './racket';
 export {RGACompiler} from './rga';
 export {RubyCompiler} from './ruby';
 export {RustcCgGCCCompiler} from './rustc-cg-gcc';
diff --git a/lib/compilers/racket.ts b/lib/compilers/racket.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d64b5d5a075f58d9003c464c5e323bd1e8175301
--- /dev/null
+++ b/lib/compilers/racket.ts
@@ -0,0 +1,122 @@
+// Copyright (c) 2022, Compiler Explorer Authors
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright notice,
+//       this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+
+import path from 'path';
+
+import {CompilationResult, ExecutionOptions} from '../../types/compilation/compilation.interfaces';
+import {ParseFilters} from '../../types/features/filters.interfaces';
+import {BaseCompiler} from '../base-compiler';
+import {logger} from '../logger';
+
+export class RacketCompiler extends BaseCompiler {
+    private raco: string;
+
+    static get key() {
+        return 'racket';
+    }
+
+    constructor(info, env) {
+        // Disable output filters, as they currently don't do anything
+        if (!info.disabledFilters) {
+            info.disabledFilters = ['labels', 'directives', 'commentOnly', 'trim'];
+        }
+        super(info, env);
+        this.raco = this.compilerProps(`compiler.${this.compiler.id}.raco`);
+    }
+
+    override optionsForFilter(filters: ParseFilters, outputFilename: string, userOptions?: string[]): string[] {
+        // We currently always compile to bytecode first and then decompile.
+        // Forcing `binary` on like this ensures `objdump` will be called for
+        // the decompilation phase.
+        filters.binary = true;
+
+        return [];
+    }
+
+    override supportsObjdump(): boolean {
+        return true;
+    }
+
+    override getSharedLibraryPathsAsArguments(libraries: object[], libDownloadPath?: string): string[] {
+        return [];
+    }
+
+    override async runCompiler(
+        compiler: string,
+        options: string[],
+        inputFilename: string,
+        execOptions: ExecutionOptions,
+    ): Promise<CompilationResult> {
+        if (!execOptions) {
+            execOptions = this.getDefaultExecOptions();
+        }
+
+        if (!execOptions.customCwd) {
+            execOptions.customCwd = path.dirname(inputFilename);
+        }
+
+        // Compile to bytecode via `raco make`
+        options.unshift('make');
+        const makeResult = await this.exec(this.raco, options, execOptions);
+
+        return this.transformToCompilationResult(makeResult, inputFilename);
+    }
+
+    override getOutputFilename(dirPath: string, outputFilebase: string, key?: any): string {
+        return path.join(dirPath, 'compiled', `${this.compileFilename.replace('.', '_')}.zo`);
+    }
+
+    override async objdump(
+        outputFilename: any,
+        result: any,
+        maxSize: number,
+        intelAsm: any,
+        demangle: any,
+        filters: ParseFilters,
+    ): Promise<any> {
+        // Decompile to assembly via `raco decompile` with `disassemble` package
+        const execOptions: ExecutionOptions = {
+            maxOutput: maxSize,
+            customCwd: (result.dirPath as string) || path.dirname(outputFilename),
+        };
+        const decompileResult = await this.exec(this.raco, ['decompile', outputFilename], execOptions);
+
+        if (decompileResult.code) {
+            logger.error('Error decompiling via `raco decompile`', decompileResult);
+            result.asm = `<No output: \`raco decompile\` returned ${decompileResult.code}>`;
+        }
+
+        result.objdumpTime = decompileResult.execTime;
+        result.asm = this.postProcessObjdumpOutput(decompileResult.stdout);
+
+        return result;
+    }
+
+    override processAsm(result: any, filters: any, options: any) {
+        // TODO: Process and highlight decompiled output
+        return {
+            asm: [{text: result.asm}],
+        };
+    }
+}
diff --git a/lib/languages.ts b/lib/languages.ts
index 303e999bb28f4031259a81c132eb5648d54ce03f..7feacbc0ca8ab831d3a739dab0e78e01053e803f 100644
--- a/lib/languages.ts
+++ b/lib/languages.ts
@@ -471,6 +471,17 @@ const definitions: Record<LanguageKey, LanguageDefinition> = {
         previewFilter: null,
         monacoDisassembly: null,
     },
+    racket: {
+        name: 'Racket',
+        monaco: 'scheme',
+        extensions: ['.rkt'],
+        alias: [],
+        logoUrl: 'racket.svg',
+        logoUrlDark: null,
+        formatter: null,
+        previewFilter: null,
+        monacoDisassembly: 'scheme',
+    },
     ruby: {
         name: 'Ruby',
         monaco: 'ruby',
diff --git a/types/languages.interfaces.ts b/types/languages.interfaces.ts
index d99e550b748cb4c0518ca99037c8022d08788ee8..4bae853861bf8002cfedccd17519bc052023efcd 100644
--- a/types/languages.interfaces.ts
+++ b/types/languages.interfaces.ts
@@ -62,6 +62,7 @@ export type LanguageKey =
     | 'pascal'
     | 'pony'
     | 'python'
+    | 'racket'
     | 'ruby'
     | 'rust'
     | 'scala'
diff --git a/views/resources/logos/racket.svg b/views/resources/logos/racket.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d5c05d0bfea9826a2b2c08f954cc1e6751d11903
--- /dev/null
+++ b/views/resources/logos/racket.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="circle_pieces" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
+	 y="0px" width="511.875px" height="511.824px" viewBox="0 0 511.875 511.824" enable-background="new 0 0 511.875 511.824"
+	 xml:space="preserve">
+<circle id="circle" fill="#FFFFFF" cx="256.252" cy="255.986" r="253.093"/>
+<path id="blue-piece" fill="#3E5BA9" d="M455.398,412.197c33.792-43.021,53.946-97.262,53.946-156.211
+	c0-139.779-113.313-253.093-253.093-253.093c-30.406,0-59.558,5.367-86.566,15.197C272.435,71.989,408.349,247.839,455.398,412.197z
+	"/>
+<path id="left-red-piece" fill="#9F1D20" d="M220.003,164.337c-39.481-42.533-83.695-76.312-130.523-98.715
+	C36.573,112.011,3.159,180.092,3.159,255.986c0,63.814,23.626,122.104,62.597,166.623
+	C100.111,319.392,164.697,219.907,220.003,164.337z"/>
+<path id="bottom-red-piece" fill="#9F1D20" d="M266.638,221.727c-54.792,59.051-109.392,162.422-129.152,257.794
+	c35.419,18.857,75.84,29.559,118.766,29.559c44.132,0,85.618-11.306,121.74-31.163C357.171,381.712,317.868,293.604,266.638,221.727
+	z"/>
+</svg>
diff --git a/webpack.config.esm.js b/webpack.config.esm.js
index 631e9c257d1829ea24600dfa938675216ac9f09b..a65e4e2ebd84762b20aaabfdd51bb8614d136e6a 100644
--- a/webpack.config.esm.js
+++ b/webpack.config.esm.js
@@ -64,6 +64,7 @@ const plugins = [
             'dart',
             'typescript',
             'solidity',
+            'scheme',
         ],
         filename: isDev ? '[name].worker.js' : `[name]${webjackJsHack}worker.[contenthash].js`,
     }),