diff --git a/docs/src/main/asciidoc/images/websockets-next-architecture.png b/docs/src/main/asciidoc/images/websockets-next-architecture.png
new file mode 100644
index 0000000000000..0cd6bca7ca3cd
Binary files /dev/null and b/docs/src/main/asciidoc/images/websockets-next-architecture.png differ
diff --git a/docs/src/main/asciidoc/images/websockets-next-chat.png b/docs/src/main/asciidoc/images/websockets-next-chat.png
new file mode 100644
index 0000000000000..20b05b71803da
Binary files /dev/null and b/docs/src/main/asciidoc/images/websockets-next-chat.png differ
diff --git a/docs/src/main/asciidoc/websockets-next-reference.adoc b/docs/src/main/asciidoc/websockets-next-reference.adoc
new file mode 100644
index 0000000000000..f2b1a92d6960b
--- /dev/null
+++ b/docs/src/main/asciidoc/websockets-next-reference.adoc
@@ -0,0 +1,548 @@
+////
+This guide is maintained in the main Quarkus repository
+and pull requests should be submitted there:
+https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
+////
+= WebSockets-Next extension reference guide
+:extension-status: preview
+include::_attributes.adoc[]
+:numbered:
+:sectnums:
+:categories: web
+:topics: web,websockets
+:extensions: io.quarkus:quarkus-websockets-next
+
+IMPORTANT: The `websockets-next` extension is experimental. The proposal API may change in future releases.
+
+== The WebSocket protocol
+
+The _WebSocket_ protocol, documented in the https://datatracker.ietf.org/doc/html/rfc6455[RFC6455], establishes a standardized method for creating a bidirectional communication channel between a client and a server through a single TCP connection.
+Unlike HTTP, WebSocket operates as a distinct TCP protocol but is designed to function seamlessly alongside HTTP.
+For example, it reuses the same ports and is compatible with the same security mechanisms.
+
+The interaction using WebSocket initiates with an HTTP request employing the 'Upgrade' header to transition to the WebSocket protocol.
+Instead of a `200 OK` response, the server replies with a `101 Switching Protocols` response to upgrade the HTTP connection to a WebSocket connection.
+Following this successful handshake, the TCP socket utilized in the initial HTTP upgrade request remains open, allowing both client and server to exchange messages in both direction continually.
+
+== HTTP and WebSocket architecture styles
+
+Despite WebSocket's compatibility with HTTP and its initiation through an HTTP request, it's crucial to recognize that the two protocols lead to distinctly different architectures and programming models.
+
+With HTTP/REST, applications are structured around resources/endpoints that handle various HTTP methods and paths.
+Client interaction occurs through emitting HTTP requests with appropriate methods and paths, following a request-response pattern.
+The server routes incoming requests to corresponding handlers based on path, method, and headers and then replies with a well-defined response.
+
+Conversely, WebSocket typically involves a single endpoint for the initial HTTP connection, after which all messages utilize the same TCP connection.
+It introduces an entirely different interaction model: asynchronous and message-driven.
+
+WebSocket is a low-level transport protocol, in contrast to HTTP.
+Message formats, routing, or processing require prior agreement between the client and server regarding message semantics.
+
+For WebSocket clients and servers, the `Sec-WebSocket-Protocol` header in the HTTP handshake request allows negotiation of a higher-level messaging protocol. In its absence, the server and client must establish their own conventions.
+
+== Quarkus WebSockets vs. Quarkus WebSockets Next
+
+This guide utilizes the `quarkus-websockets-next` extension, an implementation of the WebSocket API boasting enhanced efficiency and usability compared to the legacy `quarkus-websockets` extension.
+The original `quarkus-websockets` extension remains accessible, will receive ongoing support, but it's unlikely to receive to feature development.
+
+Unlike `quarkus-websockets`, the `quarkus-websockets-next` extension does **not** implement the Jakarta WebSocket specification.
+Instead, it introduces a modern API, prioritizing simplicity of use.
+Additionally, it's tailored to integrate with Quarkus' reactive architecture and networking layer seamlessly.
+
+The annotations utilized by the Quarkus WebSockets next extension differ from those in JSR 356 despite, sometimes, sharing the same name.
+The JSR annotations carry a semantic that the Quarkus WebSockets Next extension does not follow.
+
+== Use the WebSockets Next extension
+
+To use the `websockets-next` extension, you need to add the `io.quarkus.quarkus-websockets-next` extension to your project.
+In your `pom.xml` file, add:
+
+[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
+.pom.xml
+----
+
+ io.quarkus
+ quarkus-websockets-next
+
+----
+
+[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
+.build.gradle
+----
+implementation("io.quarkus:quarkus-websockets-next")
+----
+
+
+== Configure the WebSocket server
+
+The WebSocket handling reuses the _main_ HTTP server.
+
+Thus, the configuration of the WebSocket server is done in the `quarkus.http.` configuration section.
+
+WebSocket paths configured within the application are concatenated with the root path defined by `quarkus.http.root` (which defaults to /).
+This concatenation ensures that WebSocket endpoints are appropriately positioned within the application's URL structure.
+
+Refer to the xref:http-reference.adoc[HTTP guide] for more details.
+
+== Declare WebSocket endpoints
+
+To declare web socket endpoints, you need to create a class annotated with `@io.quarkus.websockets.next.WebSocket` and define the path of the WebSocket endpoint:
+
+[source,java]
+----
+package org.acme.websockets;
+
+import io.quarkus.websockets.next.WebSocket;
+import jakarta.inject.Inject;
+
+@WebSocket(path = "/chat/{username}")
+public class ChatWebSocket {
+
+}
+----
+
+Thus, client can connect to this web socket endpoint using `ws://localhost:8080/chat/your-name`.
+If TLS is used, the URL is `wss://localhost:8443/chat/your-name`.
+
+=== Path parameters
+
+The path of the WebSocket endpoint can contain path parameters.
+The syntax is the same as for JAX-RS resources: `{parameterName}`.
+
+Access to the path parameter values is done through the `io.quarkus.websockets.next.WebSocketConnection` _session_ object:
+
+[source,java]
+----
+@Inject io.quarkus.websockets.next.WebSocketConnection session;
+// ...
+String value = session.pathParam("parameterName");
+----
+
+Path parameter values are always strings.
+If the path parameter is not present in the path, the `pathParam` method returns `null`.
+
+NOTE: Query parameters are not supported. However, you can access the query using `session.handshakeRequest().query()`
+
+=== Sub-websockets endpoints
+
+A class annotated with `@WebSocket` can encapsulate static nested classes, which are also annotated with `@WebSocket` and represent _sub-web_ sockets.
+The resulting path of these sub-web sockets concatenates the path from the enclosing class and the nested class.
+The resulting path is normalized, following the HTTP URL rules.
+
+Sub-web sockets inherit access to the path parameters declared in the `@WebSocket` annotation of both the enclosing and nested classes.
+The `consumePrimary` method within the enclosing class can access the `version` parameter in the following example.
+Meanwhile, the `consumeNested` method within the nested class can access both `version` and `id` parameters:
+
+[source, java]
+----
+@WebSocket("/ws/v{version}")
+public class MyPrimaryWebSocket {
+
+ @OnTextMessage
+ void consumePrimary(String s) { ... }
+
+ @WebSocket("/products/{id}")
+ public static class MyNestedWebSocket {
+
+ @OnTextMessage
+ void consumeNested(String s) { ... }
+
+ }
+
+}
+----
+
+=== CDI Scopes for WebSocket Endpoints
+Classes annotated with `@WebSocket` are managed as CDI beans, allowing for flexible scope management within the application.
+By default, WebSocket endpoints are considered in the singleton pseudo-scope.
+However, developers can specify alternative scopes to suit their specific requirements:
+
+[source,java]
+----
+@WebSocket("/ws")
+public class MyWebSocket {
+ // Singleton scoped bean
+}
+
+@WebSocket("/ws")
+@ApplicationScoped
+public class MyRequestScopedWebSocket {
+ // Application scoped.
+}
+----
+
+Furthermore, each WebSocket connection is associated with its own _session_ scope.
+When the `@OnOpen` method is invoked, a session scope corresponding to the WebSocket connection is established.
+Subsequent calls to `@On[Text|Binary]Message` or `@OnClose` methods utilize this same session scope.
+The session scope remains active until the `@OnClose` method completes execution, at which point it is terminated.
+
+The `WebSocketConnection` object, which represents the connection itself, is also a session-scoped bean, allowing developers to access and manage WebSocket-specific data within the context of the session.
+
+In cases where a WebSocket endpoint does not declare an `@OnOpen` method, the session scope is still created.
+It remains active until the connection terminates, regardless of the presence of an `@OnClose` method.
+
+Methods annotated with `@OnTextMessage,` `@OnBinaryMessage,` `@OnOpen`, and `@OnClose` also have the request scoped activated for the duration of the method execution (until it produced its result).
+
+
+=== WebSocket endpoint methods
+
+A WebSocket endpoint comprises the following components:
+
+* Path: This is the URL path where the WebSocket connection is established (e.g., ws://localhost:8080/).
+* At most one `@OnTextMessage` method: Handles the connected client's text messages.
+* At most one `@OnBinaryMessage` method: Handles the binary messages the connected client sends.
+* At most one `@OnOpen` method: Invoked when a client connects to the WebSocket.
+* At most one `@OnClose` method: Executed upon the client disconnecting from the WebSocket.
+
+Only some endpoints need to include all methods.
+However, it must contain at least `@On[Text|Binary]Message` or `@OnOpen`.
+
+An error is thrown at build time if any endpoint violates these rules.
+The static nested classes representing sub-websockets adhere to the same guidelines.
+
+IMPORTANT: Any methods annotated with `@OnTextMessage`, `@OnBinaryMessage`, `@OnOpen`, and `@OnClose` outside a WebSocket endpoint are considered erroneous and will result in the build failing with an appropriate error message.
+
+== Processing messages
+
+Method receiving messages from the client are annotated with `@OnTextMessage` or `@OnBinaryMessage`.
+
+`OnTextMessage` are invoked for every _text_ message received from the client.
+`OnBinaryMessage` are invoked for every _binary_ message the client receives.
+
+=== Invocation Rules
+
+When invoking these annotated methods, the _session_ scope linked to the WebSocket connection remains active.
+In addition, the request scope is active until the completion of the method (or until it produces its result for async and reactive methods).
+
+Quarkus WebSocket Next supports _blocking_ and _non-blocking_ logic, akin to Quarkus REST, determined by the method signature and additional annotations such as `@Blocking` and `@NonBlocking`.
+
+Here are the rules governing execution:
+
+* Non-blocking methods must execute on the connection's event loop.
+* Methods annotated with `@RunOnVirtualThread` are considered blocking and should execute on a virtual thread.
+* Blocking methods must execute on a worker thread if not annotated with `@RunOnVirtualThread`.
+* When `@RunOnVirtualThread` is employed, each invocation spawns a new virtual thread.
+* Methods returning `CompletionStage` and `Uni` are considered non-blocking
+* Methods returning `Multi` are considered non-blocking and must be subscribed to, except if they return their own `Multi`.
+* Methods returning `void` or plain objects are considered blocking.
+
+=== Parameters
+
+These methods can accept parameters in two formats:
+
+* The message object (of any type).
+* A `Multi` with X as the message type.
+* Any other parameters should be flagged as errors.
+
+The message object represents the data sent and can be accessed as either raw content (`String`, `JsonObject`, `JsonArray`, `Buffer` or `byte[]`) or deserialized high-level objects, which is the recommended approach.
+
+When receiving a `Multi`, the method is invoked once per connection, and the provided `Multi` receives the items transmitted by this connection.
+The method must subscribe to the `Multi` to receive these items (or return a Multi).
+Cancelling this subscription closes the associated connection.
+
+=== Allowed Returned Types
+
+Methods annotated with `@OnTextMessage` or `@OnBinaryMessage` can return various types to handle WebSocket communication efficiently:
+
+* `void`: Indicates a blocking method where no explicit response is sent back to the client.
+* `Uni`: Denotes a non-blocking method where the completion of the returned Uni signifies the end of processing. No explicit response is sent back to the client.
+* An object of type `X` represents a blocking method in which the returned object is serialized and sent back to the client as a response.
+* `Uni`: Specifies a non-blocking method where the item emitted by the non-null `Uni` is sent to the client as a response.
+* `Multi`: Indicates a non-blocking method where the items emitted by the non-null `Multi` are sequentially sent to the client until completion or cancellation.
+
+Here are some examples of these methods:
+
+[source, java]
+----
+@OnTextMessage
+void consume(Message m) {
+// Process the incoming message. The method is called on an executor thread for each incoming message.
+}
+
+@OnTextMessage
+Uni consumeAsync(Message m) {
+// Process the incoming message. The method is called on an event loop thread for each incoming message.
+// The method completes when the returned Uni emits its item.
+}
+
+@OnTextMessage
+ReponseMessage process(Message m) {
+// Process the incoming message and send a response to the client.
+// The method is called for each incoming message.
+// Note that if the method returns `null`, no response will be sent to the client.
+}
+
+@OnTextMessage
+Uni processAsync(Message m) {
+// Process the incoming message and send a response to the client.
+// The method is called for each incoming message.
+// Note that if the method returns `null`, no response will be sent to the client. The method completes when the returned Uni emits its item.
+}
+
+OnTextMessage
+Multi stream(Message m) {
+// Process the incoming message and send multiple responses to the client.
+// The method is called for each incoming message.
+// The method completes when the returned Multi emits its completion signal.
+// The method cannot return `null` (but an empty multi if no response must be sent)
+}
+----
+
+When returning a Multi, Quarkus subscribes to the returned Multi automatically and writes the emitted items until completion, failure, or cancellation. Failure or cancellation terminates the connection.
+
+=== Streams
+
+In addition to individual messages, WebSocket endpoints can handle streams of messages.
+In this case, the method receives a `Multi` as a parameter.
+Each instance of `X` is deserialized using the same rules listed above.
+
+The method receiving the `Multi` can either return another `Multi` or `void`.
+If the method returns a `Multi`, it does not have to subscribe to the incoming `multi`:
+
+[source, java]
+----
+@OnTextMessage
+public Multi stream(Multi incoming) {
+ return incoming.log();
+}
+----
+
+This approach allows bi-directional streaming.
+
+When the method returns `void`, it must subscribe to the incoming `Multi`:
+
+[source, java]
+----
+@OnTextMessage
+public void stream(Multi incoming) {
+ incoming.subscribe().with(item -> log(item));
+}
+----
+
+=== Skipping reply
+When a method is intended to produce a message written to the client, it can emit `null`.
+Emitting `null` signifies no response to be sent to the client, allowing for skipping a response when needed.
+
+=== JsonObject and JsonArray
+Vert.x `JSONObject` and `JSONArray` instances bypass the serialization and deserialization mechanisms.
+Messages are sent as text messages.
+
+=== Broadcasting
+By default, responses produced by `@On[Text|Binary]Message` methods are sent back to the connected client.
+However, using the `broadcast` parameter, responses can be broadcasted to all connected clients.
+
+[source, java]
+----
+@OnTextMessage(broadcast=true)
+String emitToAll(String message) {
+ // Send the response to all connected clients.
+}
+----
+
+The same principle applies to methods returning instances of `Multi` or `Uni`.
+
+== OnOpen and OnClose methods
+
+The WebSocket endpoint can also be notified when a client connects or disconnects.
+
+This is done by annotating a method with `@OnOpen` or `@OnClose`:
+
+[source,java]
+----
+@OnOpen(broadcast = true)
+public ChatMessage onOpen() {
+ return new ChatMessage(MessageType.USER_JOINED, connection.pathParam("username"), null);
+}
+
+@Inject WebSocketConnection connection;
+
+@OnClose
+public void onClose() {
+ ChatMessage departure = new ChatMessage(MessageType.USER_LEFT, connection.pathParam("username"), null);
+ connection.broadcast().sendTextAndAwait(departure);
+}
+----
+
+`@OnOpen` is triggered upon client connection, while `@OnClose` is invoked upon disconnection.
+
+These methods have access to the _session-scoped_ `WebSocketConnection` bean.
+
+=== Parameters
+
+Methods annotated with `@OnOpen` and `@OnClose` do not accept any parameters.
+If such methods declare parameters, they will be flagged as errors and reported at build time.
+
+=== Allowed Returned Types
+
+`@OnOpen` and `@OnClose` methods support different returned types.
+
+For `@OnOpen` methods, the same rules as `@On[Text|Binary]Message` apply.
+Thus, a method annotated with `@OnOpen` can send messages to the client immediately after connecting.
+The supported return types for `@OnOpen` methods are:
+
+* `void`: Indicates a blocking method where no explicit message is sent back to the connected client.
+* `Uni`: Denotes a non-blocking method where the completion of the returned `Uni` signifies the end of processing. No message is sent back to the client.
+* An object of type `X`: Represents a blocking method where the returned object is serialized and sent back to the client.
+* `Uni`: Specifies a non-blocking method where the item emitted by the non-null `Uni` is sent to the client.
+* `Multi`: Indicates a non-blocking method where the items emitted by the non-null `Multi` are sequentially sent to the client until completion or cancellation.
+
+Items sent to the client are serialized except for the `String`, `JsonObject`, `JsonArray`, `Buffer`, and `byte[]` types.
+In the case of `Multi`, Quarkus subscribes to the returned `Multi` and writes the items to the `WebSocket` as they are emitted.
+`String`, `JsonObject` and `JsonArray` are sent as text messages.
+`Buffers` and byte arrays are sent as binary messages.
+
+For `@OnClose` methods, the allowed return types are:
+
+* `void`: The method is considered blocking.
+* `Uni`: The method is considered non-blocking.
+
+`@OnClose` methods cannot send items to the connection client by returning objects.
+They can only send messages to the other client by using the `WebSocketConnection` object.
+
+=== Server-side Streaming
+
+Methods annotated with `@OnOpen` can utilize server-side streaming by returning a `Multi`:
+
+[source, java]
+----
+@WebSocket("/foo")
+@OnOpen
+public Multi streaming() {
+ return Multi.createFrom().ticks().every(Duration.ofSecond(1))
+ .onOverflow().ignore();
+}
+----
+
+=== Broadcasting with @OnOpen
+
+Similar to `@On[Text|Binary]Message`, items sent to the client from a method annotated with `@OnOpen` can be broadcasted to all clients instead of just the connecting client:
+
+[source, java]
+----
+@OnOpen(broadcast=true)
+String onOpen() {
+ return "We have a new member!";
+}
+----
+
+== Access to the WebSocketConnection
+
+The `io.quarkus.websockets.next.WebSocketConnection` object represents the WebSocket connection.
+It's _session-scoped_ and is valid for the whole duration of the connection.
+
+Methods annotated with `@OnOpen`, `@OnTextMessage`, `@OnBinaryMessage`, and `@OnClose` can access the `WebSocketConnection` object:
+
+[source,java]
+----
+@Inject WebSocketConnection connection;
+----
+
+Note that outside of these methos, the `WebSocketConnection` object is not available.
+
+The connection can be used to send messages to the client, access the path parameters, and broadcast messages to all connected clients.
+
+[source, java]
+----
+// Send a message:
+connection.sendTextAndAwait("Hello!");
+
+// Broadcast messages:
+connection.broadcast().sendTextAndAwait(departure);
+
+// Access path parameters:
+String param = connection.pathParam("foo");
+----
+
+The `WebSocketConnection` provides both a blocking and a non-blocking method to send messages:
+
+- `sendTextAndAwait(String message)`: Sends a text message to the client and waits for the message to be sent. It's blocking and should only be called from an executor thread.
+- `sendText(String message)`: Sends a text message to the client. It returns a `Uni`. It's non-blocking, but you must subscribe to it.
+
+== Serialization and Deserialization
+
+The WebSocket Next extension supports automatic serialization and deserialization of messages.
+
+
+Objects of type `String`, `JsonObject`, `JsonArray`, `Buffer`, and `byte[]` are sent as-is and by-pass the serialization and deserialization.
+When no codec is provided, the serialization and deserialization uses JSON (Jackson) automatically.
+
+When you need to customize the serialization and deserialization, you can provide a custom codec.
+
+=== Custom codec
+
+To implement a custom codec, you must provides a CDI bean implementing:
+
+- `io.quarkus.websockets.next.BinaryMessageCodec` for binary messages
+- `io.quarkus.websockets.next.TextMessageCodec` for text messages
+
+The following example shows how to implement a custom codec for a `Item` class:
+
+[source, java]
+----
+@Singleton
+ public static class ItemBinaryMessageCodec implements BinaryMessageCodec- {
+
+ @Override
+ public boolean supports(Type type) {
+ // Allows selecting the right codec for the right type
+ return type.equals(Item.class);
+ }
+
+ @Override
+ public Buffer encode(Item value) {
+ // Serialization
+ return Buffer.buffer(value.toString());
+ }
+
+ @Override
+ public Item decode(Type type, Buffer value) {
+ return new Item(value.toString());
+ }
+
+ }
+----
+
+`OnTextMessage` and `OnBinaryMessage` methods can also specify which codec need to be used explicitly:
+
+[source, java]
+----
+@OnTextMessage(codec = MyInputCodec.class) // <1>
+Item find(Item item) {
+ //....
+}
+----
+1. Specify the codec to use for both the deserialization and serialization of the message
+
+When the serialization and deserialization must use a different codec, you can specify the codec to use for the serialization and deserialization separately:
+
+[source, java]
+----
+@OnTextMessage(
+ codec = MyInputCodec.class, // <1>
+ outputCodec = MyOutputCodec.class // <2>
+Item find(Item item) {
+ //....
+}
+----
+1. Specify the codec to use for both the deserialization of the incoming message
+2. Specify the codec to use for the serialization of the outgoing message
+
+== Handle Pong message
+
+The `@OnPongMessage` annotation is used to consume pong messages.
+A websocket endpoint must declare at most one method annotated with `@OnPongMessage`.
+
+The method must accept a single parameter of type `Buffer`:
+
+[source,java]
+----
+@OnPongMessage
+void pong(Buffer data) {
+ // ....
+}
+----
+
+[[websocket-next-configuration-reference]]
+== Configuration reference
+
+include::{generated-dir}/config/quarkus-websockets-next.adoc[opts=optional, leveloffset=+1]
diff --git a/docs/src/main/asciidoc/websockets-next-tutorial.adoc b/docs/src/main/asciidoc/websockets-next-tutorial.adoc
new file mode 100644
index 0000000000000..fb5f2ad82e9a2
--- /dev/null
+++ b/docs/src/main/asciidoc/websockets-next-tutorial.adoc
@@ -0,0 +1,178 @@
+////
+This guide is maintained in the main Quarkus repository
+and pull requests should be submitted there:
+https://github.com/quarkusio/quarkus/tree/main/docs/src/main/asciidoc
+////
+= Getting started with WebSockets-Next
+include::_attributes.adoc[]
+:categories: web
+:diataxis-type: tutorial
+:summary: This guide explains how your Quarkus application can utilize web sockets to create interactive web applications. This guide uses the WebSockets Next extension
+:topics: web,websockets
+:extensions: io.quarkus:quarkus-websockets-next
+
+This guide explains how your Quarkus application can utilize web sockets to create interactive web applications.
+In this guide, we will develop a very simple chat application using web sockets to receive and send messages to the other connected users.
+
+IMPORTANT: The `websockets-next` extension is experimental. The proposal API may change in future releases.
+
+== Prerequisites
+
+include::{includes}/prerequisites.adoc[]
+
+== Quarkus WebSockets vs. Quarkus WebSockets Next
+
+This guide uses the `quarkus-websockets-next` extension.
+This extension is a new implementation of the WebSocket API that is more efficient and easier to use than the original `quarkus-websockets` extension. The original `quarkus-websockets` extension is still available and will continue to be supported.
+
+Unlike `quarkus-websockets`, `quarkus-web-socket-next` does NOT implement https://jakarta.ee/specifications/websocket/[Jakarta WebSocket].
+Instead, it provides a simplified and more modern API that is easier to use.
+It is also designed to work efficiently with Quarkus' reactive programming model and the Quarkus' networking layer.
+
+== What you'll learn
+
+* How to use the `quarkus-websockets-next` extension
+* How to declare a web socket endpoint
+* How to send and receive messages using web sockets
+* How to broadcast messages to all connected users
+* How to be notified of new connections and disconnections
+* How to use _path parameters_ in web socket URLs
+
+== Architecture
+
+In this guide, we create a straightforward chat application using web sockets to receive and send messages to the other connected users.
+
+image:websockets-next-architecture.png[alt=Architecture]
+
+== Solution
+
+We recommend that you follow the instructions in the next sections and create the application step by step.
+However, you can skip right to the completed example.
+
+Clone the Git repository: `git clone {quickstarts-clone-url}`, or download an {quickstarts-archive-url}[archive].
+
+The solution is located in the `websockets-next-quickstart` link:{quickstarts-tree-url}/websockets-next-quickstart[directory].
+
+== Creating the Maven project
+
+First, we need a new project. Create a new project with the following command:
+
+:create-app-artifact-id: websockets-quickstart
+:create-app-extensions: websockets
+include::{includes}/devtools/create-app.adoc[]
+
+This command generates the project (without any classes) and imports the `websockets-next` extension.
+
+If you already have your Quarkus project configured, you can add the `websockets-next` extension
+to your project by running the following command in your project base directory:
+
+:add-extension-extensions: websockets-next
+include::{includes}/devtools/extension-add.adoc[]
+
+This will add the following to your build file:
+
+[source,xml,role="primary asciidoc-tabs-target-sync-cli asciidoc-tabs-target-sync-maven"]
+.pom.xml
+----
+
+ io.quarkus
+ quarkus-websockets-next
+
+----
+
+[source,gradle,role="secondary asciidoc-tabs-target-sync-gradle"]
+.build.gradle
+----
+implementation("io.quarkus:quarkus-websockets-next")
+----
+
+== Declaring a WebSocket endpoint
+
+Our application contains a single class that handles the web sockets.
+Create the `org.acme.websockets.ChatWebSocket` class in the `src/main/java` directory.
+Copy the following content into the created file:
+
+[source,java]
+----
+package org.acme.websockets;
+
+import io.quarkus.websockets.next.OnClose;
+import io.quarkus.websockets.next.OnOpen;
+import io.quarkus.websockets.next.OnTextMessage;
+import io.quarkus.websockets.next.WebSocket;
+import io.quarkus.websockets.next.WebSocketConnection;
+import jakarta.inject.Inject;
+
+@WebSocket(path = "/chat/{username}") // <1>
+public class ChatWebSocket {
+
+ // Declare the type of messages that can be sent and received
+ public enum MessageType {USER_JOINED, USER_LEFT, CHAT_MESSAGE}
+ public record ChatMessage(MessageType type, String from, String message) {
+ }
+
+ @Inject
+ WebSocketConnection connection; // <2>
+
+ @OnOpen(broadcast = true) // <3>
+ public ChatMessage onOpen() {
+ return new ChatMessage(MessageType.USER_JOINED, connection.pathParam("username"), null);
+ }
+
+ @OnClose // <4>
+ public void onClose() {
+ ChatMessage departure = new ChatMessage(MessageType.USER_LEFT, connection.pathParam("username"), null);
+ connection.broadcast().sendTextAndAwait(departure);
+ }
+
+ @OnTextMessage(broadcast = true) // <5>
+ public ChatMessage onMessage(ChatMessage message) {
+ return message;
+ }
+
+}
+----
+<1> Declares the web socket endpoint and configure the path. Note that the path can contain a path parameter: `username`.
+<2> A _session scoped bean_ that represents the connection to the client. It allows sending messages programmatically and retrieve the path parameters.
+<3> This method is called when a new client connects. The `broadcast = true` attribute indicates that the returned message should be sent to all connected clients.
+<4> This method is called when a client disconnects. The method uses the `WebSocketConnection` to broadcast a message to all remaining connected clients.
+<5> This method is called when a client sends a message. The `broadcast = true` attribute indicates that the returned message should be sent to all connected clients. Here, we just returns the received (text) message.
+
+As you can see, Quarkus handles the web socket lifecycle and message handling using annotations.
+It also serializes and deserializes messages using JSON automatically.
+
+== A slick web frontend
+
+All chat applications need a _nice_ UI, well, this one may not be that nice, but does the work.
+Quarkus automatically serves static resources contained in the `META-INF/resources` directory.
+Create the `src/main/resources/META-INF/resources` directory and copy this link:{quickstarts-blob-url}/websockets-next-quickstart/src/main/resources/META-INF/resources/index.html[index.html] file in it.
+
+== Run the application
+
+Now, let's see our application in action. Run it with:
+
+include::{includes}/devtools/dev.adoc[]
+
+Then open your 2 browser windows to http://localhost:8080/:
+
+1. Enter a name in the top text area (use 2 different names).
+2. Click on connect
+3. Send and receive messages
+
+image:websockets-next-chat.png[alt=Application]
+
+As usual, the application can be packaged using:
+
+include::{includes}/devtools/build.adoc[]
+
+And executed using `java -jar target/quarkus-app/quarkus-run.jar`.
+
+You can also build the native executable using:
+
+include::{includes}/devtools/build-native.adoc[]
+
+
+== Conclusion
+
+This short getting started guide has shown you how to create a simple chat application using the `quarkus-websockets-next` extension.
+Learn more about this extension on the xref:./websockets-next-reference.adoc[dedicated reference guide].