# Manual Installation (without txAdmin) (/docs/getting-started/manual-installation)

This page shows how to install ESX Legacy without the txAdmin recipe. Use it when you deploy with your own scripts or Docker, when you add ESX to an existing server, or when you want to know exactly what the recipe does. If you just want a working server, the [txAdmin recipe](/docs/getting-started/installation) is faster.

## Overview [#overview]

You need four things:

1. A FiveM server build and a `server.cfg`
2. A MariaDB/MySQL database with the ESX schema from `legacy.sql`
3. The resources: `oxmysql`, `esx_lib`, `es_extended` and the other `[core]` resources, plus optional addons
4. The correct start order in `server.cfg`

## Step by step [#step-by-step]

<Steps>
<Step>
### Prepare the server build [#prepare-the-server-build]

Download the latest server build for your OS from [runtime.fivem.net](https://runtime.fivem.net/artifacts/fivem/) and extract it into its own folder, for example `C:\FXServer\server` or `/opt/fxserver/server`. ESX Legacy refuses player connections on builds older than **10188**, so do not use an old build.

Create a separate data folder next to it, for example `C:\FXServer\esx-server`. Your `server.cfg` and `resources` folder go there.
</Step>

<Step>
### Create the database [#create-the-database]

Create an empty database with the `utf8mb4` character set. In HeidiSQL, DBeaver or the MariaDB console:

```sql
CREATE DATABASE `es_extended` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- Optional but recommended: a dedicated user instead of root
CREATE USER 'esx'@'localhost' IDENTIFIED BY 'change-me';
GRANT ALL PRIVILEGES ON `es_extended`.* TO 'esx'@'localhost';
FLUSH PRIVILEGES;
```

`legacy.sql` does not contain a `CREATE DATABASE` statement. You must create the database first and import the file into it.
</Step>

<Step>
### Download ESX [#download-esx]

Download these repositories (use the latest release, or the `main` branch if you know what you are doing):

| Repository | What you need from it |
| --- | --- |
| [esx-framework/esx_core](https://github.com/esx-framework/esx_core/releases) | the `[core]` folder and `[SQL]/legacy.sql` |
| [esx-framework/ESX-Legacy-Addons](https://github.com/esx-framework/ESX-Legacy-Addons) | the `[esx_addons]` folder (optional) |
| [overextended/oxmysql](https://github.com/overextended/oxmysql/releases/latest) | the release zip `oxmysql.zip`, not the source code |

<Callout type="warn" title="Use the oxmysql release zip">
The oxmysql source code on GitHub must be built before it runs. Always download `oxmysql.zip` from the releases page. A source download starts but fails with missing file errors.
</Callout>

The recipe also adds `ox_lib`, `pma-voice` (voice chat), `bob74_ipl` (interiors), `sd-phone` and `sd-phone-props`. They are not required by `es_extended`, but you probably want voice and interiors on a roleplay server.
</Step>

<Step>
### Import legacy.sql [#import-legacysql]

Import `[SQL]/legacy.sql` into the database you created. In HeidiSQL: select the database, then **File > Run SQL file**. From the command line:

```bash
mysql -u esx -p es_extended < "legacy.sql"
```

The file creates the core tables (`users`, `items`, `jobs`, `job_grades`, `licenses`, `owned_vehicles` and more) and the tables used by the official addons (`addon_account`, `billing`, `datastore`, `vehicles`, `banking` and others).

<Callout type="info">
Most statements are plain `CREATE TABLE`, so importing the file a second time into the same database fails with "table already exists". Import once into an empty database. Later schema changes are handled by the ESX migrations (see [Updating](/docs/getting-started/updating)).
</Callout>
</Step>

<Step>
### Copy the resources [#copy-the-resources]

Put the folders into `resources`. Folder names in square brackets are *categories*: FiveM searches inside them, and you can start a whole category with `ensure [name]`.

<Files>
  <Folder name="esx-server" defaultOpen>
    <File name="server.cfg" />
    <Folder name="resources" defaultOpen>
      <Folder name="[core]" defaultOpen>
        <Folder name="es_extended" />
        <Folder name="esx_lib" />
        <Folder name="esx_multicharacter" />
        <Folder name="esx_identity" />
        <Folder name="esx_skin" />
        <Folder name="skinchanger" />
        <Folder name="esx_notify" />
        <Folder name="esx_context" />
        <Folder name="..." />
      </Folder>
      <Folder name="[esx_addons]">
        <Folder name="esx_policejob" />
        <Folder name="esx_banking" />
        <Folder name="..." />
      </Folder>
      <Folder name="[standalone]" defaultOpen>
        <Folder name="oxmysql" />
        <Folder name="ox_lib" />
        <Folder name="pma-voice" />
        <Folder name="bob74_ipl" />
      </Folder>
    </Folder>
  </Folder>
</Files>

Check that each resource folder directly contains its `fxmanifest.lua`. A common mistake is a double folder like `oxmysql/oxmysql/fxmanifest.lua` after extracting a zip, or a version suffix like `es_extended-main`. The folder name is the resource name, so `es_extended` must be called exactly that.
</Step>

<Step>
### Write server.cfg [#write-servercfg]

Start from the `server.cfg` that ships in `esx_core`. The important part is the order at the end:

```bash title="server.cfg"
set onesync on
set mysql_connection_string "mysql://esx:change-me@localhost:3306/es_extended?charset=utf8mb4"

## Default resources
ensure chat
ensure spawnmanager
ensure hardcap

## Database driver and library first
ensure oxmysql
ensure esx_lib

## ESX core
ensure es_extended
ensure [core]

## Standalone resources and addons
ensure [standalone]
ensure [esx_addons]
```

`oxmysql` lives inside `[standalone]`, so `ensure [standalone]` lists it a second time. The official recipe uses the same layout. The explicit `ensure oxmysql` line is what guarantees it starts before `es_extended`, so keep `oxmysql` and `esx_lib` above `es_extended` as shown.

Add your license key (`sv_licenseKey`), endpoints and the admin ACEs. The full file is explained in [server.cfg for ESX](/docs/getting-started/server-cfg).
</Step>

<Step>
### Start the server [#start-the-server]

From the data folder, start the build and point it at your config:

```bash
# Windows (run from C:\FXServer\esx-server)
C:\FXServer\server\FXServer.exe +exec server.cfg

# Linux (run from /opt/fxserver/esx-server)
bash /opt/fxserver/server/run.sh +exec server.cfg
```

On the first start you should see oxmysql connect to your database, then `es_extended` run its migrations. If it prints `Server restart required!`, stop and start the server once.
</Step>
</Steps>

## Why the start order matters [#why-the-start-order-matters]

`es_extended` declares `oxmysql` and `esx_lib` as dependencies and loads `@oxmysql/lib/MySQL.lua` and `@esx_lib/imports.lua` from them. Every other ESX resource loads `@es_extended/imports.lua`, which calls `exports['es_extended']:getSharedObject()`. If a resource starts before `es_extended`, that export does not exist yet and you get errors like `No such export getSharedObject in resource es_extended` or `attempt to index a nil value (global 'ESX')`.

FiveM starts the dependencies listed in a manifest automatically, but only if it can find them. Keeping the explicit order in `server.cfg` makes failures obvious and keeps your own scripts (which often forget to declare dependencies) behind the core.

| Order | Resource | Why |
| --- | --- | --- |
| 1 | `oxmysql` | Database connection used by everything else |
| 2 | `esx_lib` | Library loaded by `es_extended` |
| 3 | `es_extended` | Creates the `ESX` object |
| 4 | `[core]` | UI, identity, multicharacter, skin |
| 5 | `[standalone]`, `[esx_addons]` | Jobs, shops and third-party scripts |
| 6 | your own resources | Always after the core |

## Running without the addons [#running-without-the-addons]

The addons are optional. A minimal server only needs `oxmysql`, `esx_lib`, `es_extended` and the `[core]` folder. If you leave out addons, you can still keep their tables in the database. Unused tables do nothing.

If you remove a `[core]` resource, check what depends on it first. For example `esx_multicharacter` declares `esx_context`, `esx_identity` and `esx_skin` as dependencies and will not start without them.

## Common issues [#common-issues]

- **`Couldn't find resource es_extended`**: the folder is named differently or sits one level too deep. Check `resources/[core]/es_extended/fxmanifest.lua` exists.
- **`Table 'es_extended.users' doesn't exist`**: `legacy.sql` was imported into another database than the one in your connection string.
- **oxmysql cannot connect**: see [Troubleshooting](/docs/getting-started/troubleshooting#oxmysql-cannot-connect-to-the-database).

## Related [#related]

- [Install with txAdmin](/docs/getting-started/installation)
- [server.cfg for ESX](/docs/getting-started/server-cfg)
- [Database schema](/docs/guides/database-schema)
- [oxmysql guide](/docs/guides/oxmysql)
