Browse docs

Installation

Install Free Phone on a FiveM server, configure its required dependencies, and verify the first startup.

Free Phone

Free Phone is a complete FiveM smartphone with an iPhone-inspired Sky UI, persistent devices, physical or virtual SIM cards, calls, messages, social networks, media apps, server services, games, and custom-app compatibility.

The production frontend is included in the release. A normal server installation does not require Node.js, pnpm, or a frontend build.

Requirements

TypeSupported options
DatabaseMySQL or MariaDB with oxmysql
FrameworkESX Legacy, Qbox, or QBCore
Inventoryox, QB, LJ, QS, CodeM, Core, MF, or SMX Inventory
CallsPMA Voice or SaltyChat
RadioYACA, PMA Voice, or SaltyChat

Start the selected framework, inventory, and voice resources before sky_phone.

Install the resource

Copy Free Phone

Copy the release into your FiveM resources directory and keep the folder name exactly sky_phone.

Configure the server

Open these two files:

sky_phone/config/config.lua
sky_phone/config/media.lua

At minimum, verify the framework, inventory, locale, phone-item name, device mode, SIM mode, and voice provider. Automatic provider detection is available for the framework and inventory.

config/config.lua
Config.Bridge = {
    Framework = "auto",
    Inventory = "auto",
    Locale = "en",
    Debug = false,
}

Config.Phone = {
    Item = "phone",
    Unique = true,
    Keybind = "F1",
    AllowMovement = true,
}

Config.Sim.Enabled = true

Add inventory items

ox_inventory

Update config

Set unique phones to true. Free Phone always uses the configured phone item, so it has no separate Config.Item.Require option.

config/config.lua
Config.Phone.Unique = true
Config.Bridge.Inventory = "ox"

Setting Config.Bridge.Inventory is optional when automatic detection already selects ox_inventory.

Add the phone item to ox_inventory

If an item named phone already exists, replace its complete definition. Add the following to ox_inventory/data/items.lua:

ox_inventory/data/items.lua
["phone"] = {
    label = "Phone",
    weight = 190,
    stack = false,
    consume = 0
},

Copy phone.png from sky_phone/inventory_images into ox_inventory/web/images.

Remove the NPWD integration

Search the complete ox_inventory resource for Item('phone'. Current releases place the handler in ox_inventory/modules/items/client.lua; older releases can use ox_inventory/items/client.lua. Remove this complete NPWD block when it exists:

ox_inventory/modules/items/client.lua
Item('phone', function(data, slot)
    local success, result = pcall(function()
        return exports.npwd:isPhoneVisible()
    end)

    if success then
        exports.npwd:setPhoneVisible(not result)
    end
end)

Do not add a client.event, client.export, LB Phone event, or LB Phone export to the item. Free Phone listens for the used ox_inventory slot and validates it server-side.

Restart your server

Restart the complete server to load the updated item and remove the old NPWD integration.

qb-inventory

This guide is for qb-inventory 2.0.0. Forks may store shared items or images elsewhere.

Update config

Set unique phones to true. Free Phone always uses the configured phone item, so it has no separate Config.Item.Require option.

config/config.lua
Config.Phone.Unique = true
Config.Bridge.Inventory = "qb"

Setting Config.Bridge.Inventory is optional when automatic detection already selects qb-inventory.

Update items data

Open qb-core/shared/items.lua, search for phone, and replace its complete definition with the following:

qb-core/shared/items.lua
phone = {
    name = 'phone',
    label = 'Phone',
    weight = 190,
    type = 'item',
    image = 'phone.png',
    unique = true,
    useable = true,
    shouldClose = true,
    description = 'Free Phone'
},

Copy phone.png from sky_phone/inventory_images into qb-inventory/html/images, unless the file already exists. Free Phone registers the usable item through QBCore and stores the phone data in the inventory info metadata.

Restart your server

Restart the complete server to load the updated QB-Core item definition.

Add physical SIM items

When Config.Sim.Enabled = true, also add the registered and anonymous SIM items for your inventory. Both SIM items must always be unique. The ready-to-copy definitions are available in sky_phone/README.md, and the matching images are included in sky_phone/inventory_images.

When Config.Sim.Enabled = false, the two SIM items are not required.

Add the start order

Add Free Phone after its dependencies in server.cfg:

server.cfg
ensure oxmysql
ensure es_extended
ensure ox_inventory
ensure pma-voice
ensure sky_phone

Replace the example framework, inventory, and voice resources with the providers used by your server.

For QB-Core with qb-inventory, the corresponding order is:

server.cfg
ensure oxmysql
ensure qb-core
ensure qb-inventory
ensure pma-voice
ensure sky_phone

Start and verify

Restart the server and inspect the console. Free Phone creates and upgrades its database tables automatically, then registers the configured phone item. A manual SQL import is normally not required.

Use the phone item or press F1 to open the phone. The key can be rebound in FiveM's key bindings.

Manual database installation

Hosts that require a manual schema import can run:

sky_phone/sql/install.sql

Keep runtime migrations enabled after the import because they install future schema upgrades.

First-start checklist

  • The server console reports the selected framework and inventory without errors.
  • The configured phone item opens the phone.
  • Unique phones receive a persistent IMEI and do not stack.
  • A physical SIM provides cellular service, or automatic numbers work when SIMs are disabled.
  • Calls have audio through the configured voice provider.
  • Light and dark modes render correctly.
  • The server-owned pepper values have been replaced and stored safely before production use.

Production setup guide

Review the following settings before opening a production server. Restart sky_phone after changing Lua configuration.

Configuration files

FilePurpose
config/config.luaFramework, inventory, devices, SIMs, calls, apps, permissions, limits, and providers
config/media.luaFiveManage, GIPHY, upload limits, and Gallery import websites
config/locales/en.luaCanonical English locale and fallback structure
config/locales/de.luaGerman locale overrides
config/music/Server-owned MP3/OGG tracks and optional artwork

Framework, inventory, and locale

config/config.lua
Config.Bridge = {
    Framework = "auto", -- auto, esx, qbox, qb
    Inventory = "auto", -- auto, ox, qb, lj, qs, codem, core, mf, smx
    Locale = "en",      -- en or de
    CallbackTimeout = 15000,
    Debug = false,
}

Use explicit provider values when automatic detection could select the wrong resource. Debug mode adds diagnostic information; warnings and errors are always printed.

Choose a device mode

Config.Phone.Unique = true
ModeBehavior
trueEach phone item has its own IMEI. Settings, apps, account link, local data, and SIM follow that item. The item must not stack.
falseEach framework character receives one persistent virtual device. Any configured phone item opens that device.

With unique phones, using an item selects that exact handset. The F1 key reopens the last selected IMEI; when no handset has been selected, the server chooses the first concrete phone slot.

Choose a SIM mode

Config.Sim.Enabled = true
ModeBehavior
trueCellular service requires a registered or anonymous physical SIM item.
falseDevices without a SIM receive a persistent automatic number. Physical SIM items are not required.

Test device- or SIM-mode changes on a database copy before applying them to an existing production server.

Configure calls and radio

Config.Calls.VoiceProvider = "pma" -- pma, pma-voice, saltychat, salty
Config.Radio.VoiceProvider = "auto" -- auto, yaca, pma, saltychat

Start the selected voice resource before Free Phone. Radio's automatic selection checks YACA, PMA Voice, and SaltyChat. Configure restricted frequencies in Config.Radio.LockedChannels and display-name permissions in Config.Radio.DisplayName.AllowedJobs.

Configure media

Add the FiveManage V3 Media API token to the server-loaded media file:

config/media.lua
Config.Media.FiveManage.ApiKey = "your-fivemanage-v3-media-token"
Config.Media.GiphyApiKey = "your-giphy-api-key"

Without a valid FiveManage token, Camera uploads, video uploads, Voice Memo uploads, and FiveManage Gallery imports are unavailable. Limit Gallery import origins through Config.Media.Import.Websites; direct URLs are accepted only from configured HTTPS hosts.

Configure server-owned music

Place MP3 or OGG files anywhere below config/music/. Optional artwork can use WEBP, PNG, JPG, or JPEG. Define stable tracks in Config.Music.Tracks:

Config.Music.Tracks = {
    {
        Id = "night-drive",
        Title = "Night Drive",
        Artist = "Sky Records",
    },
}

Name files after the track ID, for example night-drive.ogg and night-drive.webp. Restart Free Phone after adding tracks; no frontend rebuild is required.

Set production security values

Replace all three bundled values before players create passcodes or social accounts:

Config.Server = {
    PasscodePepper = "replace-with-a-long-random-value",
    FlipTokPasswordPepper = "replace-with-another-random-value",
    PicstagramPasswordPepper = "replace-with-a-third-random-value",
}
Keep each value private, different, and stable. Changing a pepper invalidates the passcodes or passwords protected by that value.

Players must treat Sky Cloud and social-app credentials as in-character roleplay credentials and must never reuse real-world passwords.

Configure optional apps

  • Select a Garage provider in Config.Garage.System.
  • Select a Housing provider in Config.Housing.System.
  • Define company jobs, profiles, services, phone numbers, permissions, and availability under Config.Companies.Definitions.
  • Configure Weazel News editorial jobs and grades under Config.WeazelNews.AllowedJobs.
  • Add trusted external CrewLink ping resources to Config.CrewLink.ExternalPingResources.
  • Configure custom-app origins, storage ceilings, rate limits, and adapters under Config.CustomApps.

Disable development tools

Before production, review:

Config.Phone.DevelopmentCommand = false
Config.TestData.Enabled = false
Config.Bridge.Debug = false

Migrate from LB Phone

Free Phone detects supported LB Phone tables but never starts an import automatically.

Back up the database

Create a complete backup before previewing or importing data.

Preview the migration

Run from the server console:

skyphone:migrate lb-phone dry

Import and verify

skyphone:migrate lb-phone

Restart the resource and verify accounts, devices, calls, messages, media, and social apps. Use force for an idempotent retry or remove to remove data created by the migration.

Update safely

  1. Back up the database.
  2. Back up config/config.lua, config/media.lua, and custom music or media.
  3. Preserve all three production pepper values.
  4. Replace the resource files.
  5. Merge new configuration options instead of overwriting the new config blindly.
  6. Restart Free Phone and review all warnings and errors.
Continue with the Exports and Events pages when integrating external resources.