Configuration
The Blixt resource reads config.json from its resource root on startup.
Edit the file and restart the resource to apply changes — there is no
hot reload yet.
The Lua bootstrap (dist/game/server/config.lua) parses the file with
FXServer’s strict JSON parser, so:
- No comments (
//or/* */) — they will fail parsing. - No trailing commas.
- Underscore-prefixed keys (
_doc,_comment,_phone_comment) are ignored by the loader’s sanitiser. Use them as inline notes if you want. - If parsing fails, the resource boots with defaults and logs
[blixt] config.json parse error: <reason>.
A reference copy lives next to config.json as config.example.json —
keep it as your working memory of what each field does.
Top-level shape
Section titled “Top-level shape”{ "phone": { /* DeviceConfig */ }, "tablet": { /* DeviceConfig */ }, "audioRecordingEnabled": true, "esim": { /* EsimConfig */ }, "business": { /* BusinessConfig */ }, "maps": { /* MapsConfig */ }, "debug": { "enabled": false, "level": "info" }}phone and tablet share the same DeviceConfig shape; they’re listed
separately because the two devices have independent home layouts, defaults,
and disabled-app sets. The tablet supports one extra field, toggleKey.
DeviceConfig
Section titled “DeviceConfig”disabledApps: string[]
Section titled “disabledApps: string[]”App IDs to hide on this device. Hidden apps don’t appear on the home
screen, in the app switcher, or in the App Store. Use this to replace a
built-in app with your own (e.g. ship your own banking resource and add
"banking" here to suppress the built-in).
Built-in IDs:
settings, notes, memo, contacts, messages, dialer, calculator, clock,camera, gallery, bump, fun, social, glimpse, marketplace, bills, calendar,jobs, garage, mail, banking, govid, store, directory, business, maps,properties, weather, healthDefault: [].
featuredApps: string[]
Section titled “featuredApps: string[]”App IDs pinned to the Featured strip at the top of the App Store.
Accepts both built-in IDs (above) and external app IDs registered via
RegisterExternalApp. Leave empty to show only externally-flagged
featured apps.
Default: [].
homeOrder: string[]
Section titled “homeOrder: string[]”Initial ordering of icons on the home screen for new characters only. Listed apps come first in the given order; remaining apps follow in registration order. Existing characters with a saved layout are unaffected.
Phone default starts with:
["messages", "contacts", "dialer", "camera", "gallery", "maps", "calendar", "mail"]
Tablet default starts with:
["calendar", "mail", "notes", "marketplace", "garage", "jobs", "directory"]
home.requiredApps: string[] (optional)
Section titled “home.requiredApps: string[] (optional)”Additional app IDs whose launchers must remain on the home screen. The default policy already protects the core apps; add to this list when an external app is mission-critical to your server and should be un-removable.
Default: [].
wallpapers: ConfigWallpaper[]
Section titled “wallpapers: ConfigWallpaper[]”Server-owner-defined wallpapers. Each entry:
{ "id": "company-hq", // required, unique "url": "https://cdn.example.com/x.webp", // required "urlLight": "https://cdn.example.com/y.webp", // optional, light-mode variant "label": "Company HQ" // optional, display name}URLs may be:
- Absolute (
https://...) — served from your CDN. - Relative — resolved against the device NUI’s
html/folder. To serve a wallpaper from the resource itself, drop the image intoresources/blixt/dist/html/wallpapers/x.webpand use"url": "wallpapers/x.webp". Same idea for the tablet’shtml/folder.
defaults.wallpaperId may reference one of these IDs or one of the
built-ins: blixt, coast, pier, storm.
Default: [].
defaults (legacy alias)
Section titled “defaults (legacy alias)”First-boot settings applied to new characters only. Existing settings
are preserved across config edits. This legacy block covers the three
original appearance defaults. New installs should prefer
settings.defaults for expanded phone configuration.
{ "theme": "dark", // "light" | "dark" "language": "en", // any locale code present in the i18n bundle "wallpaperId": null // string ID or null}Blixt currently bundles en (English) and sv (Swedish) as stable locales,
plus draft locales for de (German), fr (French), and pt-BR (Portuguese,
Brazil). The language value must match one of the bundled locale codes.
settings.defaults
Section titled “settings.defaults”Expanded first-boot player setting defaults. These seed new characters only; saved player settings still win after a player has used the phone.
{ "brightness": 80, // 0-100 "notificationSound": "default", "ringtone": "classic", "showBatteryPercentage": true, "textScale": 1, // 0.8-1.4 "reduceMotion": false, "streamerMode": false, "skipBootAnimation": false, "position": "bottom-right", // phone overlay position "scale": 1, // 0.5-1.5 "marginX": 20, "marginY": 20}Supported keys:
theme, language, wallpaperId, airplaneMode, wifi, bluetooth,doNotDisturb, brightness, notificationSound, ringtone, scale,showBatteryPercentage, textScale, reduceMotion, streamerMode,skipBootAnimation, position, marginX, marginYDo not put identity or runtime state here. phoneNumber, displayName,
flashlight, customWallpaperUrl, faceUnlockEnrolled, and
recentSearches are intentionally not config defaults.
branding.deviceName: string (optional)
Section titled “branding.deviceName: string (optional)”The visible device name in the status bar and lock screen. Falls back to the brand default (“Blixt” / “Blixt Tablet”) when absent.
videoCallsEnabled: boolean (optional)
Section titled “videoCallsEnabled: boolean (optional)”Whether the device may initiate or receive video calls. Defaults differ
per device (phone true, tablet false). Set explicitly to override.
tablet.toggleKey: string (tablet-only, optional)
Section titled “tablet.toggleKey: string (tablet-only, optional)”Default keyboard binding for the /tablet command. Empty string means no
default — players can still bind it themselves under FiveM Settings → Key
Bindings → Blixt → Toggle Tablet.
FiveM only applies this default on the player’s first encounter; once
they’ve bound (or explicitly cleared) it, their choice persists. Use
FiveM input names: F2, GRAVE, INSERT, etc.
Default: "".
audioRecordingEnabled
Section titled “audioRecordingEnabled”Server-wide kill switch for in-NUI audio capture. When false, the Memo
app is hidden and players cannot record voice memos, voicemail greetings,
or voicemail messages. Existing recorded audio can still be played where
the UI exposes it.
Default: true.
{ "lineToggleEnabled": true, "anonymousCallerIdEnabled": true}lineToggleEnabledcontrols whether players can activate/deactivate their eSIM line from Settings.anonymousCallerIdEnabledcontrols whether players can hide outbound call caller ID. SMS/messages still use the real number.
Defaults: both true.
business
Section titled “business”{ "seedArchetypes": true, "allowPlayerCreate": true}seedArchetypesseeds the bundled example Businesses on boot.allowPlayerCreateis a legacy direct-create flag. Ordinary player creation now goes through Business Formation; keep this enabled unless you know your server has a custom Business setup.
Defaults: both true.
{ "staticBlips": [ { "id": "pillbox-hospital", "label": "Pillbox Hill Medical", "position": { "x": 358, "y": -592 }, "color": "#ef4444", "icon": "cross" } ]}staticBlips are server-authored map markers broadcast to every player.
id, label, and position are required. color accepts a CSS color,
and icon may name a supported lucide icon.
Default: [].
{ "enabled": false, "level": "info" // "error" | "warn" | "info" | "debug" | "trace"}When enabled is true:
- The Winston logger emits at the configured level.
- The
_devtRPC router is mounted (used by the dev API and end-to-end test harness).
These can also come from convars blixt:debug and blixt:debugLevel.
When those runtime flags are explicitly set, they override config.json so
txAdmin/server.cfg can enable or disable development surfaces without editing
the resource JSON.
Default: { "enabled": false, "level": "info" }.
Worked example
Section titled “Worked example”A roleplay server that:
- ships its own
bankingandmessagesapps and disables the built-ins - features a custom government app on the App Store
- uses two branded wallpapers
- defaults new characters to light theme
{ "phone": { "disabledApps": ["banking", "messages"], "featuredApps": ["my-gov-app"], "homeOrder": ["dialer", "my-messages", "contacts", "my-banking", "camera"], "home": { "requiredApps": ["my-gov-app"] }, "wallpapers": [ { "id": "skyline-day", "url": "https://cdn.myserver.com/wp/skyline-day.webp", "label": "City skyline (day)" }, { "id": "skyline-night", "url": "https://cdn.myserver.com/wp/skyline-night.webp", "label": "City skyline (night)" } ], "defaults": { "theme": "light", "language": "en", "wallpaperId": "skyline-day" }, "settings": { "defaults": { "brightness": 85, "ringtone": "modern", "notificationSound": "chime", "showBatteryPercentage": true, "position": "bottom-right", "scale": 1 } }, "branding": { "deviceName": "MyServer Phone" }, "videoCallsEnabled": true }, "tablet": { "disabledApps": ["dialer", "bump"], "featuredApps": [], "homeOrder": ["mail", "calendar", "marketplace"], "wallpapers": [], "defaults": { "theme": "light", "language": "en", "wallpaperId": null }, "branding": { "deviceName": "MyServer Tablet" }, "videoCallsEnabled": false, "toggleKey": "F2" }, "audioRecordingEnabled": true, "esim": { "lineToggleEnabled": true, "anonymousCallerIdEnabled": true }, "business": { "seedArchetypes": true, "allowPlayerCreate": true }, "maps": { "staticBlips": [] }, "debug": { "enabled": false, "level": "info" }}Relationship to convars
Section titled “Relationship to convars”Convars (blixt:framework, the storage providers, blixt:trusted_resources,
etc.) live in server.cfg, not in config.json. The split is
deliberate:
config.jsonshapes the player-visible product: which apps appear, what wallpapers exist, what the device is called.- Convars wire the resource to your infrastructure: framework, storage backends, trust allowlists.
See the convar reference for everything else.