rev to 3.0.0
diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml
index e25fcf6..3188bec 100644
--- a/.github/workflows/test-package.yml
+++ b/.github/workflows/test-package.yml
@@ -13,50 +13,31 @@
   PUB_ENVIRONMENT: bot.github
 
 jobs:
-  # Check code formatting and static analysis on a single OS (linux)
-  # against Dart dev.
-  analyze:
+  # Check formatting, static analysis, and run tests.
+  build:
     runs-on: ubuntu-latest
     strategy:
-      matrix:
-        sdk: [dev]
-    steps:
-      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
-      - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
-        with:
-          sdk: ${{ matrix.sdk }}
-      - id: install
-        name: Install dependencies
-        run: dart pub get
-      - name: Check formatting
-        run: dart format --output=none --set-exit-if-changed .
-        if: always() && steps.install.outcome == 'success'
-      - name: Analyze code
-        run: dart analyze
-        if: always() && steps.install.outcome == 'success'
-
-  test:
-    needs: analyze
-    runs-on: ${{ matrix.os }}
-    strategy:
       fail-fast: false
       matrix:
-        os: [ubuntu-latest]
-        sdk: [3.2.0, dev]
+        sdk: [3.2.0, stable, dev]
     steps:
       - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
       - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
         with:
           sdk: ${{ matrix.sdk }}
-      - id: install
-        name: Install dependencies
-        run: dart pub get
-      - name: Run VM tests
-        run: dart test --platform vm
-        if: always() && steps.install.outcome == 'success'
-      - name: Run Chrome tests
-        run: dart test --platform chrome
-        if: always() && steps.install.outcome == 'success'
-      - name: Run Chrome tests - wasm
-        run: dart test --platform chrome --compiler dart2wasm
-        if: always() && steps.install.outcome == 'success' && matrix.sdk == 'dev'
+      - run: dart pub get
+      - run: dart analyze --fatal-infos
+      - run: dart format --output=none --set-exit-if-changed .
+        if: ${{ matrix.sdk == 'stable' }}
+      - run: dart test --platform vm
+      - run: dart test --platform chrome
+      - run: dart test --platform chrome --compiler dart2wasm
+
+  # Run analysis against the oldest supported pub constraints.
+  downgrade:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
+      - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d
+      - run: dart pub downgrade
+      - run: dart analyze --fatal-infos
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 44c0784..a913740 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,10 @@
-## 2.4.2
+## 3.0.0
+
+- Update the underlying web implementation from using `dart:html` to using
+  `package:web` (this had also been published as `2.4.1`).
+
+## 2.4.2 (retracted)
+
 - Allow `web: '>=0.3.0 <0.5.0'`
 
 ## 2.4.1
diff --git a/README.md b/README.md
index ec4c736..d68495a 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,21 @@
 [![CI](https://github.com/dart-lang/web_socket_channel/actions/workflows/test-package.yml/badge.svg?branch=master)](https://github.com/dart-lang/web_socket_channel/actions/workflows/test-package.yml)
+[![pub package](https://img.shields.io/pub/v/web_socket_channel.svg)](https://pub.dev/packages/web_socket_channel)
+[![package publisher](https://img.shields.io/pub/publisher/web_socket_channel.svg)](https://pub.dev/packages/web_socket_channel/publisher)
 
-The `web_socket_channel` package provides [`StreamChannel`][stream_channel]
-wrappers for WebSocket connections. It provides a cross-platform
-[`WebSocketChannel`][WebSocketChannel] API, a cross-platform implementation of
-that API that communicates over an underlying [`StreamChannel`][stream_channel],
-[an implementation][IOWebSocketChannel] that wraps `dart:io`'s `WebSocket`
-class, and [a similar implementation][HtmlWebSocketChannel] that wraps
-`dart:html`'s.
+`package:web_socket_channel` provides cross-platform
+[`StreamChannel`][stream_channel] wrappers for WebSocket connections.
+
+## Docs and Usage
+
+This package provides:
+
+- a cross-platform [`WebSocketChannel`][WebSocketChannel] API
+- a cross-platform implementation of that API that communicates over an
+  underlying [`StreamChannel`][stream_channel]
+- [an implementation][IOWebSocketChannel] that wraps the `dart:io` `WebSocket`
+  class
+- and [a similar implementation][HtmlWebSocketChannel] that wraps the browser's
+  web socket implementation
 
 [stream_channel]: https://pub.dev/packages/stream_channel
 [WebSocketChannel]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel-class.html
@@ -14,16 +23,16 @@
 [HtmlWebSocketChannel]: https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel.html/HtmlWebSocketChannel-class.html
 
 It also provides constants for the WebSocket protocol's pre-defined status codes
-in the [`status.dart` library][status]. It's strongly recommended that users
-import this library with the prefix `status`.
+in the [`status.dart` library][status] (it's recommended that users import this
+library with the prefix `status`).
 
 [status]: https://pub.dev/documentation/web_socket_channel/latest/status/status-library.html
 
 ```dart
-import 'package:web_socket_channel/web_socket_channel.dart';
 import 'package:web_socket_channel/status.dart' as status;
+import 'package:web_socket_channel/web_socket_channel.dart';
 
-main() async {
+void main() async {
   final wsUrl = Uri.parse('ws://example.com');
   final channel = WebSocketChannel.connect(wsUrl);
 
@@ -36,7 +45,7 @@
 }
 ```
 
-## `WebSocketChannel`
+## The `WebSocketChannel` class
 
 The [`WebSocketChannel`][WebSocketChannel] class's most important role is as the
 interface for WebSocket stream channels across all implementations and all
diff --git a/lib/html.dart b/lib/html.dart
index e36dab0..2565169 100644
--- a/lib/html.dart
+++ b/lib/html.dart
@@ -14,10 +14,10 @@
 import 'src/exception.dart';
 import 'src/web_helpers.dart';
 
-/// A [WebSocketChannel] that communicates using a `dart:html` [WebSocket].
+/// A [WebSocketChannel] that communicates using a browser [WebSocket].
 class HtmlWebSocketChannel extends StreamChannelMixin
     implements WebSocketChannel {
-  /// The underlying `dart:html` [WebSocket].
+  /// The underlying browser [WebSocket].
   final WebSocket innerWebSocket;
 
   @override
diff --git a/lib/src/channel.dart b/lib/src/channel.dart
index 4143128..2a5f782 100644
--- a/lib/src/channel.dart
+++ b/lib/src/channel.dart
@@ -17,8 +17,8 @@
 
 /// A [StreamChannel] that communicates over a WebSocket.
 ///
-/// This is implemented by classes that use `dart:io` and `dart:html`.
-/// The [WebSocketChannel.new] constructor can also be used on any platform to
+/// This is implemented by classes that use `dart:io` and `package:web`. The
+/// [WebSocketChannel.new] constructor can also be used on any platform to
 /// connect to use the WebSocket protocol over a pre-existing channel.
 ///
 /// All implementations emit [WebSocketChannelException]s. These exceptions wrap
@@ -105,7 +105,7 @@
   /// Creates a new WebSocket handling messaging across an existing [channel].
   ///
   /// This is a cross-platform constructor; it doesn't use either `dart:io` or
-  /// `dart:html`. It's also HTTP-API-agnostic, which means that the initial
+  /// `package:web`. It's also HTTP-API-agnostic, which means that the initial
   /// [WebSocket handshake][] must have already been completed on the socket
   /// before this is called.
   ///
diff --git a/pubspec.yaml b/pubspec.yaml
index 3e1338d..0edadce 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,10 +1,6 @@
 name: web_socket_channel
-version: 2.4.2
-
-description: >-
-  StreamChannel wrappers for WebSockets. Provides a cross-platform
-  WebSocketChannel API, a cross-platform implementation of that API that
-  communicates over an underlying StreamChannel.
+version: 3.0.0
+description: Cross-platform StreamChannel wrappers for WebSocket connections.
 repository: https://github.com/dart-lang/web_socket_channel
 
 environment:
@@ -14,7 +10,7 @@
   async: ^2.5.0
   crypto: ^3.0.0
   stream_channel: ^2.1.0
-  web: '>=0.3.0 <0.5.0'
+  web: ^0.4.0
 
 dev_dependencies:
   dart_flutter_team_lints: ^2.0.0