How to Create Your Own Codex Theme
Codex lets you change more than just light mode or dark mode. A custom theme can define the app background, text color, accent color, fonts, diff colors, and a few other visual details.
You do not need to write a plugin or modify the Codex app. A Codex App theme is a short string that starts with codex-theme-v1: and contains a JSON object. Once you understand the fields, you can build and share a theme with any color palette you like.
In this guide, you will create a complete Codex App theme by hand, import it, and learn how to fix the most common errors.
This guide is for the Codex desktop app. Codex CLI themes use TextMate .tmTheme files and follow a different process.
Version note: This guide was verified against ChatGPT desktop for macOS 26.707.91948 (build 5440) on July 17, 2026. Theme sharing is supported by the app, but the complete codex-theme-v1 payload is not documented as a long-term public schema. Field names and importer behavior may change in a future release.
The finished theme
Here is the dark theme we will build:
codex-theme-v1:{"codeThemeId":"codex","theme":{"accent":"#7aa2f7","contrast":60,"fonts":{"code":null,"ui":null},"ink":"#dce3ea","opaqueWindows":true,"semanticColors":{"diffAdded":"#4fae72","diffRemoved":"#e06c75","skill":"#b48ead"},"surface":"#11161d"},"variant":"dark"}
You can copy this string and use it as a starting point. The rest of the guide explains what every value does and how to replace it safely.
How a Codex theme is structured
Every shareable Codex App theme has two parts:
codex-theme-v1:{JSON goes here}
The codex-theme-v1: prefix tells Codex which theme format it is reading. Do not remove it or add a space after it.
The JSON object contains three top-level fields:
{
"codeThemeId": "codex",
"theme": {},
"variant": "dark"
}
codeThemeIdselects the base syntax-highlighting palette.themecontains your interface colors, fonts, and semantic colors.varianttells Codex whether the theme is designed for alightordarkinterface.
Step 1: Choose light or dark
Start with the variant because it affects every color you choose later.
"variant": "dark"
Use dark when the surface is dark and the primary text is light. Use light when the surface is light and the text is dark.
The value should match the actual palette. A nearly black background with "variant": "light" may produce controls or syntax colors that are difficult to read.
Step 2: Pick the surface and ink colors
The two most important colors are surface and ink:
"surface": "#11161d",
"ink": "#dce3ea"
surfaceis the main background color.inkis the primary foreground and text color.
Choose these as a pair. The interface may look attractive in a screenshot but become tiring to use if the contrast is too low.
For a dark theme, begin with a surface between near-black and dark gray, then use an off-white ink color. For a light theme, use a soft white or pale neutral surface with a dark gray ink color. Pure black on pure white gives maximum contrast, but slightly softened colors are often more comfortable during long sessions.
You can use a contrast checker to verify that normal text has a contrast ratio of at least 4.5:1. This is especially important if you plan to share the theme with other people.
Step 3: Choose an accent color
The accent color gives the theme its identity:
"accent": "#7aa2f7"
Codex uses the accent across selected states and interactive details. It should be clearly visible against the surface without competing with the main text.
Good sources for an accent color include:
- your product or company brand color;
- a favorite editor palette;
- one distinctive color sampled from a photo;
- the complementary color of your background tint.
Avoid using the same color for the accent, added diffs, and removed diffs. Those colors communicate different things and should remain easy to distinguish.
Step 4: Set the contrast value
The contrast field controls the strength of contrast applied across parts of the interface:
"contrast": 60
A value around 45 to 70 is a practical starting range. Lower values create a softer interface; higher values make boundaries and text relationships more pronounced.
There is no single best value. Test your theme in a real conversation containing code, tool output, and a diff instead of judging it only from an empty window.
Step 5: Choose UI and code fonts
Codex lets you assign separate fonts to the interface and code:
"fonts": {
"code": null,
"ui": null
}
Leaving a value as null uses the Codex default. To use an installed font, replace null with its local font family name:
"fonts": {
"code": "SF Mono",
"ui": "Inter"
}
The font must already be installed on the computer. If you share a theme that references a custom font, tell other users which font they need. Otherwise, their system may silently fall back to another font.
Use a monospaced font for code. For ui, both sans-serif and serif fonts can work, but test longer responses and small labels before deciding.
Step 6: Define semantic colors
Semantic colors communicate meaning rather than decoration:
"semanticColors": {
"diffAdded": "#4fae72",
"diffRemoved": "#e06c75",
"skill": "#b48ead"
}
diffAddedmarks added code or content.diffRemovedmarks removed code or content.skillis used for Skill-related interface elements.
Green and red are familiar defaults for additions and removals, but they are not mandatory. If you choose another pair, make sure the colors remain distinguishable for users with color-vision differences. Bright colors may look good as small indicators but become overwhelming across a large diff, so slightly muted colors are usually safer.
Step 7: Decide whether windows should be opaque
The opaqueWindows field controls whether supported windows use a fully opaque appearance:
"opaqueWindows": true
Use true for a consistent solid background. Use false if you prefer transparency effects where the operating system and app surface support them.
If transparency reduces text clarity, switch back to true.
Step 8: Select a valid code theme ID
The example uses:
"codeThemeId": "codex"
This field controls the base code-highlighting theme. It is not the public name of your custom theme.
Some app versions have been reported to reject a new, arbitrary codeThemeId. If the Import button stays disabled even though your JSON is valid, use an ID already available in your version's code-theme dropdown, such as codex, and try again.
This is a version-dependent workaround based on a reported importer issue, not a documented guarantee. Check the current dropdown rather than assuming that every app version offers the same IDs.
Step 9: Convert the JSON into an import string
When your values are ready, place the complete JSON immediately after the version prefix:
codex-theme-v1:{"codeThemeId":"codex","theme":{"accent":"#7aa2f7","contrast":60,"fonts":{"code":null,"ui":null},"ink":"#dce3ea","opaqueWindows":true,"semanticColors":{"diffAdded":"#4fae72","diffRemoved":"#e06c75","skill":"#b48ead"},"surface":"#11161d"},"variant":"dark"}
Whitespace inside JSON is normally harmless, but a single-line string is easier to copy and share.
Before importing, check for these common JSON mistakes:
- using single quotes instead of double quotes;
- leaving a trailing comma after the last field;
- removing a closing brace;
- writing a hex color without the
#; - adding Markdown fences such as
```jsonto the copied value.
Step 10: Import the theme into Codex
To apply the theme:
- Open the Codex desktop app.
- Open Settings.
- Select Appearance.
- Open the theme import option.
- Paste the complete
codex-theme-v1:string. - Import and apply the theme.
The current Appearance documentation confirms support for changing the base theme, accent, background, foreground, UI font, and code font, and for sharing a custom theme. It does not document every field in the serialized payload. After importing, open a thread with code and a diff to verify the full palette.
How to test your theme properly
Do not stop after checking the home screen. A useful theme needs to work across several kinds of content.
Test it with:
- a long response containing headings, paragraphs, links, and inline code;
- a fenced code block with strings, comments, numbers, and keywords;
- a file diff containing both additions and removals;
- tool calls and Skill labels;
- selected and unselected controls;
- the app at both normal and reduced screen brightness.
If something feels wrong, change one variable at a time. Start with surface and ink, then adjust contrast, semantic colors, and accent. Fonts should come last because a font change can alter spacing and make an otherwise good palette feel different.
A reusable starter template
Use this template when creating another theme:
codex-theme-v1:{"codeThemeId":"codex","theme":{"accent":"#ACCENT","contrast":60,"fonts":{"code":null,"ui":null},"ink":"#FOREGROUND","opaqueWindows":true,"semanticColors":{"diffAdded":"#ADDED","diffRemoved":"#REMOVED","skill":"#SKILL"},"surface":"#BACKGROUND"},"variant":"dark"}
Replace every placeholder with a six-digit hex color and change variant when creating a light theme.
Codex App themes vs. Codex CLI themes
The Codex App and Codex CLI do not use the same theme format.
| Surface | Theme format | What it changes |
|---|---|---|
| Codex App | codex-theme-v1: JSON string | App surface, text, accent, fonts, semantic colors, and code palette |
| Codex CLI | TextMate .tmTheme file | Terminal syntax highlighting and diff colors |
For Codex CLI, place a custom .tmTheme file in $CODEX_HOME/themes, run /theme, and select it from the theme picker. An App import string cannot be renamed to .tmTheme; the formats need to be created separately.
Frequently asked questions
Can I name my custom Codex theme?
The share string does not currently include a simple display-name field. codeThemeId refers to the code-highlighting base and should not be treated as a custom name.
Why is the Import button disabled?
First validate the JSON and confirm that the string begins with codex-theme-v1:. If the structure is correct, replace a custom codeThemeId with an ID currently offered by your Codex code-theme dropdown. This workaround comes from a reported importer issue and may not apply to every version.
Can I use custom fonts?
Yes. Enter the installed font family name in fonts.ui or fonts.code. Anyone importing the theme will also need that font installed to see the same result.
Does a theme change how Codex works?
No. A theme changes appearance only. It does not change models, prompts, permissions, tools, or code behavior.
Where can I find ready-made themes?
Browse the Codex theme gallery to copy classic dark and light palettes such as Catppuccin, Dracula, Nord, Gruvbox, Solarized, One Dark, Monokai, and Rosé Pine.
Create a palette that is yours
The easiest first theme is not a completely original color system. Begin with a palette you already enjoy, adapt the background and foreground for comfortable reading, then give it one personal accent.
Once the theme works in real conversations, save the import string somewhere safe and share it. A good Codex theme is small enough to fit on one line, but it can make every coding session feel noticeably more personal.