> ## Documentation Index
> Fetch the complete documentation index at: https://flux-docs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Flux

> The root module: two constructors, two exported types, one namespace.

```luau theme={null}
local Flux = require(game:GetService("ReplicatedStorage").Flux)
```

The root module is a façade. It holds no state, guards each constructor against the wrong
context, and re-exports the `Types` namespace.

## Members

<ResponseField name="Flux.Server" type="function">
  Creates a server-side event channel. Server only.
</ResponseField>

<ResponseField name="Flux.Client" type="function">
  Creates a client-side event channel. Client only.
</ResponseField>

<ResponseField name="Flux.Types" type="Types namespace">
  The schema constructor namespace, identical to `require(Flux.Utils.Types)`. See
  [`Types`](/api/types).
</ResponseField>

<Note>
  These three are the entire public surface. There is no `ReferenceBridge`, no unified
  constructor, and no `Bridge`, `Buffers` or `Remotes` re-export. Those modules exist but
  are [internal](/api/internals/bridge).
</Note>

***

## Flux.Server()

```luau theme={null}
function Flux.Server<Args..., Out...>(
	name: string,
	schema: { Types.Type }?
): Server<Args..., Out...>
```

<ParamField path="name" type="string" required>
  The channel identifier. Both sides have to use the exact same string, and matching is
  case-sensitive. It is written into every packet, so short names cost fewer bytes.
</ParamField>

<ParamField path="schema" type="{ Types.Type }">
  An optional positional array describing the event's argument layout. When present, event
  payloads skip per-value type tags. See [Schemas](/guides/schemas).
</ParamField>

<ResponseField name="returns" type="Server<Args..., Out...>">
  A server event object. See [`Server`](/api/server).
</ResponseField>

```luau theme={null}
local Damage = Flux.Server("Damage")

local Move = Flux.Server("Move", {
	Flux.Types.Instance(),
	Flux.Types.Vector3(),
})
```

<Warning>
  Errors with `Flux.Server can only be called on the server.` when called from a client. Use
  the [shared-module pattern](/guides/shared-modules) if the call site runs in both
  contexts.
</Warning>

<Info>
  The first call initialises the transport: it creates `Flux_Reliable` and
  `Flux_Unreliable`, starts the `Heartbeat` flush loop, and installs the `OnServerEvent`
  handlers. Requiring the root module does none of that on its own, so at least one
  `Flux.Server(...)` call has to run during server startup or clients will hang waiting for
  the remotes.
</Info>

***

## Flux.Client()

```luau theme={null}
function Flux.Client<Args..., Out...>(
	name: string,
	schema: { Types.Type }?
): Client<Args..., Out...>
```

<ParamField path="name" type="string" required>
  The channel identifier. Has to match the server's exactly.
</ParamField>

<ParamField path="schema" type="{ Types.Type }">
  An optional positional argument layout. Has to be identical to the server's schema for
  the same name.
</ParamField>

<ResponseField name="returns" type="Client<Args..., Out...>">
  A client event object. See [`Client`](/api/client).
</ResponseField>

```luau theme={null}
local Damage = Flux.Client("Damage")

local Move = Flux.Client("Move", {
	Flux.Types.Instance(),
	Flux.Types.Vector3(),
})
```

<Warning>
  Errors with `Flux.Client can only be called on the client.` when called from the server.
</Warning>

<Note>
  The first client call resolves the remotes with `WaitForChild`, so it yields until the
  server has created them.
</Note>

***

## Exported types

Both types are generic over two type packs, each defaulting to `(...any)`.

<CodeGroup>
  ```luau Server theme={null}
  export type Server<Args... = (...any), Out... = (...any)> = {
  	Fire: (self: Server<Args..., Out...>, player: Player, Args...) -> (),
  	FireUnreliable: (self: Server<Args..., Out...>, player: Player, Args...) -> (),
  	FireAll: (self: Server<Args..., Out...>, Args...) -> (),
  	FireAllUnreliable: (self: Server<Args..., Out...>, Args...) -> (),
  	Connect: (self: Server<Args..., Out...>, callback: (player: Player, Args...) -> ()) -> { Disconnect: () -> () },
  	Once: (self: Server<Args..., Out...>, callback: (player: Player, Args...) -> ()) -> (),
  	Wait: (self: Server<Args..., Out...>) -> (Player, Args...),
  	OnInvoke: ((player: Player, Args...) -> Out...)?,
  }
  ```

  ```luau Client theme={null}
  export type Client<Args... = (...any), Out... = (...any)> = {
  	Fire: (self: Client<Args..., Out...>, Args...) -> (),
  	FireUnreliable: (self: Client<Args..., Out...>, Args...) -> (),
  	Invoke: (self: Client<Args..., Out...>, Args...) -> Out...,
  	Connect: (self: Client<Args..., Out...>, callback: (Args...) -> ()) -> { Disconnect: () -> () },
  	Once: (self: Client<Args..., Out...>, callback: (Args...) -> ()) -> (),
  	Wait: (self: Client<Args..., Out...>) -> Args...,
  }
  ```
</CodeGroup>

<ParamField path="Args..." type="type pack" default="(...any)">
  The arguments the event carries.
</ParamField>

<ParamField path="Out..." type="type pack" default="(...any)">
  The values an invocation returns.
</ParamField>

### Asymmetries in the type definitions

These are not oversights. They reflect what Flux actually implements.

|                                 | `Server`                                                                                                                      | `Client`                                                                                                               |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `FireAll` / `FireAllUnreliable` | <Tooltip tip="Present on this type."><Icon icon="check" color="#16a34a" /></Tooltip>                                          | <Tooltip tip="Not present on this type, so calling it is an error."><Icon icon="xmark" color="#dc2626" /></Tooltip>    |
| `Invoke`                        | <Tooltip tip="Not present on this type, so calling it is an error."><Icon icon="xmark" color="#dc2626" /></Tooltip>           | <Tooltip tip="Present on this type."><Icon icon="check" color="#16a34a" /></Tooltip>                                   |
| `OnInvoke`                      | <Tooltip tip="Present on this type."><Icon icon="check" color="#16a34a" /></Tooltip>                                          | <Tooltip tip="Not present on this type, so assigning it does nothing."><Icon icon="xmark" color="#dc2626" /></Tooltip> |
| `Player` prepended to callbacks | <Tooltip tip="Yes, the sending Player is always the first callback argument."><Icon icon="check" color="#16a34a" /></Tooltip> | <Tooltip tip="No, callbacks receive only the event's own arguments."><Icon icon="xmark" color="#dc2626" /></Tooltip>   |

<Warning>
  Because `Server` has no `Invoke` and `Client` has no `OnInvoke`, server-to-client
  invocation does not exist in Flux. Round trips run from client to server only. See
  [Invocations](/guides/invocations#direction) for the two-event alternative.
</Warning>

## Usage with generics

```luau theme={null}
local myEvent = Flux.Server("MyEvent") :: Flux.Server<{ Arg: string }>
myEvent:Fire(player, { Arg = "Hello World" })

local myInvokeEvent = Flux.Server("MyInvokeEvent") :: Flux.Server<(), (boolean, string)>
myInvokeEvent.OnInvoke = function(player)
	return true, "Success!"
end
```

See [Generics](/guides/generics) for the full treatment, including sharing packs between
the two contexts.

## Next steps

<CardGroup cols={2}>
  <Card title="Server" icon="server" href="/api/server">
    Every server method in detail.
  </Card>

  <Card title="Client" icon="desktop" href="/api/client">
    Every client method in detail.
  </Card>
</CardGroup>
