The Serial API provides a way for websites to read and write from a serial device through script. Such an API would bridge the web and the physical world, by allowing documents to communicate with devices such as microcontrollers, 3D printers, and other serial devices. There is also a companion explainer document.
This is a work in progress. All [contributions]( welcome.
## Usage example This example shows how to request an Arduino device from the user and set it up for use.
  const requestOptions = {
    // Filter on devices with the Arduino USB vendor ID.
    filters: [{ vendorId: 0x2341 }],

  // Request an Arduino from the user.
  const port = await navigator.serial.requestPort(requestOptions);

  // Open and begin reading.
  await{ baudrate: 115200 });
  const reader =;

  for await (const { done, data } of {
    if (done) break;
## Extensions to the `Navigator` interface ```webidl [Exposed=Window, SecureContext] partial interface Navigator { [SameObject] readonly attribute Serial serial; }; ``` ### serial attribute When getting, the {{Navigator/serial}} attribute always returns the same instance of the {{Serial}} object.
## Extensions to `WorkerNavigator` interface ```webidl [Exposed=DedicatedWorker, SecureContext] partial interface WorkerNavigator { [SameObject] readonly attribute Serial serial; }; ``` ### serial attribute When getting, the {{WorkerNavigator/serial}} attribute always returns the same instance of the {{Serial}} object.
## Serial interface ```webidl [Exposed=(DedicatedWorker, Window), SecureContext] interface Serial : EventTarget { attribute EventHandler onconnect; attribute EventHandler ondisconnect; Promise<sequence<SerialPort>> getPorts(); [Exposed=Window] Promise<SerialPort> requestPort(optional SerialOptions options = {}); }; ``` ### requestPort() method The {{Serial/requestPort()}} method requests access to a serial port of the user's choice (see [[[#security]]]). When the {{Serial/requestPort()}} method is invoked, the user agent MUST perform the following steps: 1. Let |promise:Promise| be [=a new promise=]. 1. Return |promise| and run the remaining steps asynchronously. 1. Request access to a serial port (see [[[#security]]]): 1. If the access request is rejected, [=reject=] |promise| with an {{"AbortError"}} {{DOMException}}. 1. Otherwise, let |port:SerialPort| be the {{SerialPort}} for which access was granted. 1. [=Resolve=] |promise| with |port|.
## SerialPort interface ```webidl [Exposed=(DedicatedWorker,Window), SecureContext] interface SerialPort { Promise<void> open(optional SerialOptions options = {}); readonly attribute ReadableStream in; readonly attribute WritableStream out; SerialPortInfo getInfo(); }; ``` ### getInfo() method The {{SerialPort/getInfo()}} method provides a means to get metadata corresponding to a {{SerialPort}} object. When the {{SerialPort/getInfo()}} method is invoked, the user agent MUST perform the steps for getting metadata of a serial port.
## SerialPortInfo interface ```webidl [Exposed=(DedicatedWorker,Window), SecureContext] interface SerialPortInfo { maplike<DOMString, DOMString?>; }; ``` ### Serial port metadata The value of certain attributes is dependent on the method that the system used to establish the serial port (e.g., USB), and so might not always be available. ### Recommended serial port metadata When available, it is RECOMMENDED that user agents populate a {{SerialPortInfo}} object with the following information. If the value of piece of metadata is unavailable(e.g., if the manufacturer is unknown), then it is RECOMMENDED that that metadata be excluded from the {{SerialPortInfo}}. For interoperability, user agents SHOULD use the values provided in they "Key" column of the table of recommended metadata.
Table of recommended metadata
Name Key Description
Serial Number `serialNumber`
Manufacturer `manufacturer`
Location ID `locationId`
Vendor ID `vendorId`
Vendor `vendor`
Product ID `productId`
Product `product`
### Getting serial port metadata The steps for getting metadata of a serial port for a |serial port| are as follows. The steps always return an instance of {{SerialPortInfo}}, which contains the related metadata. 1. Let |info:SerialPortInfo| be a newly created {{SerialPortInfo}} object. 1. Let |path:DOMString| be a {{DOMString}} that represents the path of the |serial port|. 1. Invoke |info|'s `set()` method using the string `"path"` as the key, and |path| as the value. 1. For each additional metadata item known about the |serial port|, perform the following sub-steps. Please see the table of recommended metadata for a list of recommended metadata items that SHOULD be included. 1. Let |key:DOMString| be a {{DOMString}} for the commonly used name for this key. 1. Let |value:DOMString| be a {{DOMString}} for the commonly used name for this key, or `null` otherwise. 1. Invoke |info|'s `set()` method using the string "path" as the key, and |path| as the value. 1. Return |info|.
## SerialOptions dictionary ```webidl dictionary SerialOptions { long baudrate = 9600; octet databits = 8; octet stopbits = 1; ParityType parity = "none"; long buffersize = 255; boolean rtscts = false; boolean xon = false; boolean xoff = false; boolean xany = false; }; ```
baudrate member
One of 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200, 150, 134, 110, 75, or 50.
databits member
One of 8, 7, 6, or 5.
stopbits member
One of 1 or 2.
parity member
The parity type.
## ParityType enum ```webidl enum ParityType { "none", "even", "odd", "mark", "space" }; ```
No parity bit is sent for each data word.
Data word plus parity bit has even parity.
Data word plus parity bit has odd parity.
Parity bit has a mark symbol (logical one).
Parity bit has a space symbol (logical zero).
## Security considerations This section defines the Security considerations for the Serial API. It is RECOMMENDED that an user interface be presented to the user to allow them to select the serial ports that the page can access. Such an interface would allow an end user to select zero ore more serial ports on the device - or to reject the request to access any ports. A user agent SHOULD allow the user to select from all serial ports available on the machine, and be shown an indicator for serial ports that are currently busy, either as a result of prior calls to `requestPorts()` or are in use by the system. It is also RECOMMENDED that user agents provide users with a means for the end- user to view which independently of any access request, and be given the ability to revoke individual or complete access to serial ports at any time either at the user agent level or per [=origin=].
## Use cases and requirements ### Hardware disconnection Some devices allow users to manually reset the connection between the user agent and the physical device (e.g., by pushing a button). One example device is the Arduino. Another example is the user abruptly disconnecting one device from another, thus severing the communication channel. As such, it is a requirement that the API gracefully handle abrupt disconnection caused by a reset or other event. When such disconnections occur, the API must make it possible for the developer to be notified of such disconnections. When possible, the API should provide details about the disconnection (e.g., reason, time, etc.). ### Baud rates Traditionally, serial devices have operated at [baud rates]( of between 50 and 115,200 bps. However, modern USB serial devices are able to operate at significantly higher baud rates than legacy hardware. For example, the [bioloid servos]( operate at 1 Mbit (1,000,000 bps). Other USB-to-serial chips are able to operate at 3 MBit (3,000,000bps). Additionally, other serial devices have standardized baud rates that are not in the commonly accepted value for baud rates. For example, [MIDI]( uses a baud rate of 31,250 bps, while a [DMX512 controller]( transmits data at 250kbps. As such, it is a requirement that the Serial API does not limit the baud rates to a traditional range. Instead, the API must allow a developer to specify any rate so long as the value is an unsigned number. If there is a baud rate that is common for a large range of hardware that will make use of this API, the API should provide a default baud rate value. Given the above requirement, it is possible to create software to wrap the Serial API to restrict the possible baud rates used for communicating with some particular hardware. For example, a JavaScript library that communicates with a MIDI device could automatically set the baud rate to 31,250 bps without needing to bother the developer to specify the value.
## Acknowledgements The following people contributed to the development of this document.