Andrew Levine's Blog

"use client" and "use server" are standard-ish

React Server Components are here (sort of), and there's been some changes since the original announcement. One set of changes in particular stood out to me in the Server Module Conventions v2 RFC:

Wait, What's a Directive?

Although not explicitly defined in the RFC, there's a hint at what a directive is in one of the examples:

When a Component with a "use client" directive (similar to "use strict") is imported in a "React Server" environment its exports gets replaced with a special "Reference" object

The important bit here is the similarity to Strict Mode's "use strict", originally added in ES5 (2009). As always, we can look to the spec for an authoritative answer on language features. 11.2.1 Directive Prologues and the Use Strict Directive:

A Directive Prologue is the longest sequence of ExpressionStatements occurring as the initial StatementListItems or ModuleItems of a FunctionBody, a ScriptBody, or a ModuleBody and where each ExpressionStatement in the sequence consists entirely of a StringLiteral token followed by a semicolon. The semicolon may appear explicitly or may be inserted by automatic semicolon insertion (12.10). A Directive Prologue may be an empty sequence.

A Use Strict Directive is an ExpressionStatement in a Directive Prologue whose StringLiteral is either of the exact code point sequences "use strict" or 'use strict'. A Use Strict Directive may not contain an EscapeSequence or LineContinuation.

Spec text is wordy as usual, but it boils down to the definition of two concepts:

I'm making the argument that use client is standard-ish because of the note at the end of 11.2.1, making it clear that "implemention specific" Directive Prologues are allowed:

NOTE The ExpressionStatements of a Directive Prologue are evaluated normally during evaluation of the containing production. Implementations may define implementation specific meanings for ExpressionStatements which are not a Use Strict Directive and which occur in a Directive Prologue.

Directive Examples

'use client'; // Directive, because it's at the top of a module
'use foobar'; // Directive, because it's at the top of a module and only has another directive before it

function someServerAction() {
  'use server'; // Directive, because it's at the top of a function
  'use bizzbuzz'; // Directive, because it's at the top of a function and only has another directive before it
  
  const someVal = null;
  'use bazz'; // Not a directive, because it has other code (someVal) before it in the function
}

'use client'; // Not a directive, because it has other code (someServerAction) before it in the module

Not the First, Probably Not the Last

React isn't the first tool in the JavaScript ecosystem to introduce its own directive. There's a great answer on Stack Overflow with a good collection of prior art:

Closing Thoughts

I have reservations about Server Components, but I'm happy with this particular decision from the React team. Compared to other syntatic features like JSX, I appreciate that the use of standards-based syntax ensures that existing tools in the JavaScript ecosystem (ESLint/Prettier/TypeScript/etc) will continue to work.