diff --git a/example/browser/index.js b/example/browser/index.js
index 73a66904..2426cc45 100644
--- a/example/browser/index.js
+++ b/example/browser/index.js
@@ -13,6 +13,7 @@ await Exceptionless.startup((c) => {
   c.updateSettingsWhenIdleInterval = 15000;
   c.usePersistedQueueStorage = true;
   c.setUserIdentity("12345678", "Blake");
+  c.useSessions();
 
   // set some default data
   c.defaultData["SampleUser"] = {
diff --git a/packages/angularjs/package.json b/packages/angularjs/package.json
index dddd7bc1..7b571db2 100644
--- a/packages/angularjs/package.json
+++ b/packages/angularjs/package.json
@@ -33,8 +33,8 @@
     "./package.json": "./package.json"
   },
   "scripts": {
-    "build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --sourcemap --target=es2015 --format=esm --outfile=dist/index.bundle.js && esbuild src/index.ts --bundle --minify --sourcemap --target=es2015 --format=esm --outfile=dist/index.bundle.min.js",
-    "watch": "tsc -p ../core/tsconfig.json -w --preserveWatchOutput & tsc -p tsconfig.json -w --preserveWatchOutput & esbuild src/index.ts --bundle --sourcemap --target=es2015 --format=esm --watch --outfile=dist/index.bundle.js"
+    "build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.js && esbuild src/index.ts --bundle --minify --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.min.js",
+    "watch": "tsc -p ../core/tsconfig.json -w --preserveWatchOutput & tsc -p tsconfig.json -w --preserveWatchOutput & esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --watch --outfile=dist/index.bundle.js"
   },
   "sideEffects": false,
   "publishConfig": {
diff --git a/packages/browser/package.json b/packages/browser/package.json
index e1a1621a..0838eced 100644
--- a/packages/browser/package.json
+++ b/packages/browser/package.json
@@ -45,7 +45,7 @@
     "testEnvironment": "jsdom"
   },
   "scripts": {
-    "build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.js && esbuild src/index.ts --bundle --minify --sourcemap --target=es2019 --format=esm --outfile=dist/index.bundle.min.js",
+    "build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.js && esbuild src/index.ts --bundle --minify --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.min.js",
     "watch": "tsc -p ../core/tsconfig.json -w --preserveWatchOutput & tsc -p tsconfig.json -w --preserveWatchOutput & esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --watch --outfile=dist/index.bundle.js",
     "test": "jest"
   },
diff --git a/packages/browser/src/plugins/BrowserLifeCyclePlugin.ts b/packages/browser/src/plugins/BrowserLifeCyclePlugin.ts
index 7c6188a5..c1f98065 100644
--- a/packages/browser/src/plugins/BrowserLifeCyclePlugin.ts
+++ b/packages/browser/src/plugins/BrowserLifeCyclePlugin.ts
@@ -17,12 +17,19 @@ export class BrowserLifeCyclePlugin implements IEventPlugin {
 
     this._client = context.client;
 
-    globalThis.addEventListener("beforeunload", () => void this._client?.suspend());
+    globalThis.addEventListener("beforeunload", () => {
+      if (this._client?.config.sessionsEnabled) {
+        void this._client?.submitSessionEnd();
+      }
+
+      void this._client?.suspend();
+    });
+
     document.addEventListener("visibilitychange", () => {
       if (document.visibilityState === 'visible') {
-        void this._client?.startup()
+        void this._client?.startup();
       } else {
-        void this._client?.suspend()
+        void this._client?.suspend();
       }
     });
 
diff --git a/packages/browser/tsconfig.json b/packages/browser/tsconfig.json
index 90cfe5ba..8e36fb94 100644
--- a/packages/browser/tsconfig.json
+++ b/packages/browser/tsconfig.json
@@ -3,7 +3,7 @@
   "compilerOptions": {
     "lib": [
       "DOM",
-      "ES2020"
+      "ES2021"
     ],
     "outDir": "dist",
     "rootDir": "src",
diff --git a/packages/core/package.json b/packages/core/package.json
index ecdbfcf3..ed777153 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -45,7 +45,7 @@
     "testEnvironment": "jsdom"
   },
   "scripts": {
-    "build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.js && esbuild src/index.ts --bundle --minify --sourcemap --target=es2019 --format=esm --outfile=dist/index.bundle.min.js",
+    "build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.js && esbuild src/index.ts --bundle --minify --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.min.js",
     "watch": "tsc -p tsconfig.json -w --preserveWatchOutput & esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --watch --outfile=dist/index.bundle.js",
     "test": "jest"
   },
diff --git a/packages/core/src/EventBuilder.ts b/packages/core/src/EventBuilder.ts
index 4e43a1a3..f81316ba 100644
--- a/packages/core/src/EventBuilder.ts
+++ b/packages/core/src/EventBuilder.ts
@@ -1,5 +1,5 @@
 import { ExceptionlessClient } from "./ExceptionlessClient.js";
-import { Event, KnownEventDataKeys } from "./models/Event.js";
+import { Event, EventType, KnownEventDataKeys } from "./models/Event.js";
 import { ManualStackingInfo } from "./models/data/ManualStackingInfo.js";
 import { UserInfo } from "./models/data/UserInfo.js";
 import { EventContext } from "./models/EventContext.js";
@@ -19,7 +19,7 @@ export class EventBuilder {
     this.context = context || new EventContext();
   }
 
-  public setType(type: string): EventBuilder {
+  public setType(type: EventType): EventBuilder {
     if (type) {
       this.target.type = type;
     }
diff --git a/packages/core/src/ExceptionlessClient.ts b/packages/core/src/ExceptionlessClient.ts
index 350ce1bf..d652c635 100644
--- a/packages/core/src/ExceptionlessClient.ts
+++ b/packages/core/src/ExceptionlessClient.ts
@@ -46,6 +46,10 @@ export class ExceptionlessClient {
       // TODO: Can we schedule this as part of startup?
       await queue.process();
     }
+
+    if (this.config.sessionsEnabled) {
+      await this.submitSessionStart();
+    }
   }
 
   /** Submit events, pause any timers and go into low power mode. */
@@ -175,27 +179,21 @@ export class ExceptionlessClient {
     return this.createSessionStart().submit();
   }
 
-  public async submitSessionEnd(sessionIdOrUserId: string): Promise<void> {
-    if (sessionIdOrUserId && this.config.enabled && this.config.isValid) {
-      this.config.services.log.info(
-        `Submitting session end: ${sessionIdOrUserId}`,
-      );
-      await this.config.services.submissionClient.submitHeartbeat(
-        sessionIdOrUserId,
-        true,
-      );
+  public async submitSessionEnd(sessionIdOrUserId?: string): Promise<void> {
+    const { currentSessionIdentifier, enabled, isValid, services } = this.config;
+    const sessionId = sessionIdOrUserId || currentSessionIdentifier;
+    if (sessionId && enabled && isValid) {
+      services.log.info(`Submitting session end: ${sessionId}`);
+      await services.submissionClient.submitHeartbeat(sessionId, true);
     }
   }
 
-  public async submitSessionHeartbeat(sessionIdOrUserId: string): Promise<void> {
-    if (sessionIdOrUserId && this.config.enabled && this.config.isValid) {
-      this.config.services.log.info(
-        `Submitting session heartbeat: ${sessionIdOrUserId}`,
-      );
-      await this.config.services.submissionClient.submitHeartbeat(
-        sessionIdOrUserId,
-        false,
-      );
+  public async submitSessionHeartbeat(sessionIdOrUserId?: string): Promise<void> {
+    const { currentSessionIdentifier, enabled, isValid, services } = this.config;
+    const sessionId = sessionIdOrUserId || currentSessionIdentifier;
+    if (sessionId && enabled && isValid) {
+      services.log.info(`Submitting session heartbeat: ${sessionId}`);
+      await services.submissionClient.submitHeartbeat(sessionId, false);
     }
   }
 
diff --git a/packages/core/src/configuration/Configuration.ts b/packages/core/src/configuration/Configuration.ts
index 6a934865..dd02ce51 100644
--- a/packages/core/src/configuration/Configuration.ts
+++ b/packages/core/src/configuration/Configuration.ts
@@ -5,6 +5,7 @@ import { ConsoleLog } from "../logging/ConsoleLog.js";
 import { NullLog } from "../logging/NullLog.js";
 import { UserInfo } from "../models/data/UserInfo.js";
 import { HeartbeatPlugin } from "../plugins/default/HeartbeatPlugin.js";
+import { SessionIdManagementPlugin } from "../plugins/default/SessionIdManagementPlugin.js";
 import { EventPluginContext } from "../plugins/EventPluginContext.js";
 import { EventPluginManager } from "../plugins/EventPluginManager.js";
 import { IEventPlugin } from "../plugins/IEventPlugin.js";
@@ -428,32 +429,24 @@ export class Configuration {
   }
 
   /**
-   * Set the default user identity for all events. If the heartbeat interval is
-   * greater than 0 (default: 30000ms), heartbeats will be sent after the first
-   * event submission.
+   * Set the default user identity for all events.
    */
-  public setUserIdentity(userInfo: UserInfo, heartbeatInterval?: number): void;
-  public setUserIdentity(identity: string, heartbeatInterval?: number): void;
-  public setUserIdentity(identity: string, name: string, heartbeatInterval?: number): void;
-  public setUserIdentity(userInfoOrIdentity: UserInfo | string, nameOrHeartbeatInterval?: string | number, heartbeatInterval: number = 30000): void {
-    const name: string | undefined = typeof nameOrHeartbeatInterval === "string" ? nameOrHeartbeatInterval : undefined;
+  public setUserIdentity(userInfo: UserInfo): void;
+  public setUserIdentity(identity: string): void;
+  public setUserIdentity(identity: string, name: string): void;
+  public setUserIdentity(userInfoOrIdentity: UserInfo | string, name?: string): void {
     const userInfo: UserInfo = typeof userInfoOrIdentity !== "string"
       ? userInfoOrIdentity
       : <UserInfo>{ identity: userInfoOrIdentity, name };
 
-    const interval: number = typeof nameOrHeartbeatInterval === "number" ? nameOrHeartbeatInterval : heartbeatInterval;
-    const plugin = new HeartbeatPlugin(interval);
-
     const shouldRemove: boolean = !userInfo || (!userInfo.identity && !userInfo.name);
     if (shouldRemove) {
-      this.removePlugin(plugin)
       delete this.defaultData[KnownEventDataKeys.UserInfo];
     } else {
-      this.addPlugin(plugin)
       this.defaultData[KnownEventDataKeys.UserInfo] = userInfo;
     }
 
-    this.services.log.info(`user identity: ${shouldRemove ? "null" : <string>userInfo.identity} (heartbeat interval: ${interval}ms)`);
+    this.services.log.info(`user identity: ${shouldRemove ? "null" : <string>userInfo.identity}`);
   }
 
   /**
@@ -477,7 +470,39 @@ export class Configuration {
    * This setting only works in environments that supports persisted storage.
    * There is also a performance penalty of extra IO/serialization.
    */
-  public usePersistedQueueStorage = false;
+  public usePersistedQueueStorage: boolean = false;
+
+  /**
+   * Gets or sets a value indicating whether to automatically send session start,
+   * session heartbeats and session end events.
+   */
+  public sessionsEnabled = false;
+
+  /**
+   * Internal property used to track the current session identifier.
+   */
+  public currentSessionIdentifier: string | null = null;
+
+  /**
+   *
+   * @param sendHeartbeats Controls whether heartbeat events are sent on an interval.
+   * @param heartbeatInterval The interval at which heartbeats are sent after the last sent event. The default is 1 minutes.
+   * @param useSessionIdManagement Allows you to manually control the session id. This is only recommended for single user desktop environments.
+   */
+  public useSessions(sendHeartbeats: boolean = true, heartbeatInterval: number = 60000, useSessionIdManagement: boolean = false) {
+    this.sessionsEnabled = true;
+
+    if (useSessionIdManagement) {
+      this.addPlugin(new SessionIdManagementPlugin());
+    }
+
+    const plugin = new HeartbeatPlugin(heartbeatInterval);
+    if (sendHeartbeats) {
+      this.addPlugin(plugin);
+    } else {
+      this.removePlugin(plugin);
+    }
+  }
 
   private originalSettings?: Record<string, string>;
 
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 2e88cf61..7773c1b8 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -8,7 +8,7 @@ export type { ILog } from "./logging/ILog.js";
 export { ConsoleLog } from "./logging/ConsoleLog.js";
 export { NullLog } from "./logging/NullLog.js";
 
-export type { Event, IEventData } from "./models/Event.js";
+export type { Event, EventType, IEventData } from "./models/Event.js";
 export { KnownEventDataKeys } from "./models/Event.js";
 export type { EnvironmentInfo } from "./models/data/EnvironmentInfo.js";
 export type { ManualStackingInfo } from "./models/data/ManualStackingInfo.js";
@@ -30,6 +30,7 @@ export { DuplicateCheckerPlugin } from "./plugins/default/DuplicateCheckerPlugin
 export { EventExclusionPlugin } from "./plugins/default/EventExclusionPlugin.js";
 export { HeartbeatPlugin } from "./plugins/default/HeartbeatPlugin.js";
 export { ReferenceIdPlugin } from "./plugins/default/ReferenceIdPlugin.js";
+export { SessionIdManagementPlugin } from "./plugins/default/SessionIdManagementPlugin.js";
 export { IgnoredErrorProperties, SimpleErrorPlugin } from "./plugins/default/SimpleErrorPlugin.js"
 export { SubmissionMethodPlugin } from "./plugins/default/SubmissionMethodPlugin.js";
 export { EventContext } from "./models/EventContext.js";
diff --git a/packages/core/src/models/Event.ts b/packages/core/src/models/Event.ts
index a6ee2a1a..408f513d 100644
--- a/packages/core/src/models/Event.ts
+++ b/packages/core/src/models/Event.ts
@@ -5,9 +5,11 @@ import { UserInfo } from "./data/UserInfo.js";
 import { UserDescription } from "./data/UserDescription.js";
 import { ManualStackingInfo } from "./data/ManualStackingInfo.js";
 
+export type EventType = "error" | "usage" | "log" | "404" | "session" | string;
+
 export interface Event {
   /** The event type (ie. error, log message, feature usage). */
-  type?: string;
+  type?: EventType;
   /** The event source (ie. machine name, log name, feature name). */
   source?: string;
   /** The date that the event occurred on. */
diff --git a/packages/core/src/plugins/default/HeartbeatPlugin.ts b/packages/core/src/plugins/default/HeartbeatPlugin.ts
index 1a786a3e..46a7c279 100644
--- a/packages/core/src/plugins/default/HeartbeatPlugin.ts
+++ b/packages/core/src/plugins/default/HeartbeatPlugin.ts
@@ -9,7 +9,7 @@ export class HeartbeatPlugin implements IEventPlugin {
   private _interval: number;
   private _intervalId: ReturnType<typeof setInterval> | undefined;
 
-  constructor(heartbeatInterval: number = 30000) {
+  constructor(heartbeatInterval: number = 60000) {
     this._interval = heartbeatInterval >= 30000 ? heartbeatInterval : 60000;
   }
 
@@ -34,11 +34,20 @@ export class HeartbeatPlugin implements IEventPlugin {
     clearInterval(this._intervalId);
     this._intervalId = undefined;
 
-    const user = context.event.data?.[KnownEventDataKeys.UserInfo];
-    if (user?.identity) {
+    const { config } = context.client;
+    if (!config.currentSessionIdentifier) {
+      const user = context.event.data?.[KnownEventDataKeys.UserInfo];
+      if (!user?.identity) {
+        return Promise.resolve();
+      }
+
+      config.currentSessionIdentifier = user.identity;
+    }
+
+    if (config.currentSessionIdentifier) {
       this._intervalId = setInterval(
-        () => void context.client.submitSessionHeartbeat(<string>user.identity),
-        this._interval,
+        () => void context.client.submitSessionHeartbeat(<string>config.currentSessionIdentifier),
+        this._interval
       );
     }
 
diff --git a/packages/core/src/plugins/default/ReferenceIdPlugin.ts b/packages/core/src/plugins/default/ReferenceIdPlugin.ts
index bffc9273..d8c2f14f 100644
--- a/packages/core/src/plugins/default/ReferenceIdPlugin.ts
+++ b/packages/core/src/plugins/default/ReferenceIdPlugin.ts
@@ -9,7 +9,7 @@ export class ReferenceIdPlugin implements IEventPlugin {
   public run(context: EventPluginContext): Promise<void> {
     if (!context.event.reference_id && context.event.type === "error") {
       // PERF: Optimize identifier creation.
-      context.event.reference_id = guid().replace("-", "").substring(0, 10);
+      context.event.reference_id = guid().replaceAll("-", "").substring(0, 10);
     }
 
     return Promise.resolve();
diff --git a/packages/core/src/plugins/default/SessionIdManagementPlugin.ts b/packages/core/src/plugins/default/SessionIdManagementPlugin.ts
new file mode 100644
index 00000000..09cde73f
--- /dev/null
+++ b/packages/core/src/plugins/default/SessionIdManagementPlugin.ts
@@ -0,0 +1,29 @@
+import { guid } from "../../Utils.js";
+import { EventPluginContext } from "../EventPluginContext.js";
+import { IEventPlugin } from "../IEventPlugin.js";
+
+export class SessionIdManagementPlugin implements IEventPlugin {
+  public priority = 25;
+  public name = "SessionIdManagementPlugin";
+
+  public run(context: EventPluginContext): Promise<void> {
+    const ev = context.event;
+    const isSessionStart: boolean = ev.type === "session";
+    const { config } = context.client;
+    if (isSessionStart || !config.currentSessionIdentifier) {
+      config.currentSessionIdentifier = guid().replaceAll("-", "");
+    }
+
+    if (isSessionStart) {
+      ev.reference_id = config.currentSessionIdentifier;
+    } else {
+      if (!ev.data) {
+        ev.data = {};
+      }
+
+      ev.data["@ref:session"] = config.currentSessionIdentifier;
+    }
+
+    return Promise.resolve();
+  }
+}
diff --git a/packages/core/test/plugins/default/EventExclusionPlugin.test.ts b/packages/core/test/plugins/default/EventExclusionPlugin.test.ts
index b3b681b9..5feb59b3 100644
--- a/packages/core/test/plugins/default/EventExclusionPlugin.test.ts
+++ b/packages/core/test/plugins/default/EventExclusionPlugin.test.ts
@@ -2,7 +2,7 @@ import { describe, test } from "@jest/globals";
 import { expect } from "expect";
 
 import { ExceptionlessClient } from "../../../src/ExceptionlessClient.js";
-import { Event, KnownEventDataKeys } from "../../../src/models/Event.js";
+import { Event, EventType, KnownEventDataKeys } from "../../../src/models/Event.js";
 import { InnerErrorInfo } from "../../../src/models/data/ErrorInfo.js";
 import { EventExclusionPlugin } from "../../../src/plugins/default/EventExclusionPlugin.js";
 import { EventPluginContext } from "../../../src/plugins/EventPluginContext.js";
@@ -142,7 +142,7 @@ describe("EventExclusionPlugin", () => {
   });
 
   describe("should exclude source type", () => {
-    const run = async (type: string | null | undefined, source: string | undefined, settingKey: string | null | undefined, settingValue: string | null | undefined): Promise<boolean> => {
+    const run = async (type: EventType | null | undefined, source: string | undefined, settingKey: string | null | undefined, settingValue: string | null | undefined): Promise<boolean> => {
       const client = new ExceptionlessClient();
 
       if (typeof settingKey === "string") {
diff --git a/packages/core/test/submission/TestSubmissionClient.test.ts b/packages/core/test/submission/TestSubmissionClient.test.ts
index 49f3c0aa..af8283a4 100644
--- a/packages/core/test/submission/TestSubmissionClient.test.ts
+++ b/packages/core/test/submission/TestSubmissionClient.test.ts
@@ -20,7 +20,7 @@ describe("TestSubmissionClient", () => {
     const apiFetchMock = jest.fn<(url: string, options: FetchOptions) => Promise<Response<undefined>>>()
       .mockReturnValueOnce(Promise.resolve(new Response(202, "", NaN, NaN, undefined)));
 
-    const events = [{ type: "log", message: "From js client", reference_id: "123454321" }];
+    const events: Event[] = [{ type: "log", message: "From js client", reference_id: "123454321" }];
     const client = new TestSubmissionClient(config, apiFetchMock);
     await client.submitEvents(events);
     expect(apiFetchMock).toHaveBeenCalledTimes(1);
diff --git a/packages/node/src/plugins/NodeLifeCyclePlugin.ts b/packages/node/src/plugins/NodeLifeCyclePlugin.ts
index 0ed02505..298293cc 100644
--- a/packages/node/src/plugins/NodeLifeCyclePlugin.ts
+++ b/packages/node/src/plugins/NodeLifeCyclePlugin.ts
@@ -23,6 +23,10 @@ export class NodeLifeCyclePlugin implements IEventPlugin {
         void this._client?.submitLog("beforeExit", message, "Error");
       }
 
+      if (this._client?.config.sessionsEnabled) {
+        void this._client?.submitSessionEnd();
+      }
+
       void this._client?.suspend();
       // Application will now exit.
     });
diff --git a/packages/react/package.json b/packages/react/package.json
index a142dd6b..dc54e391 100644
--- a/packages/react/package.json
+++ b/packages/react/package.json
@@ -33,7 +33,7 @@
     "./package.json": "./package.json"
   },
   "scripts": {
-    "build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.js && esbuild src/index.ts --bundle --minify --sourcemap --target=es2019 --format=esm --outfile=dist/index.bundle.min.js",
+    "build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.js && esbuild src/index.ts --bundle --minify --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.min.js",
     "watch": "tsc -p ../core/tsconfig.json -w --preserveWatchOutput & tsc -p tsconfig.json -w --preserveWatchOutput & esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --watch --outfile=dist/index.bundle.js"
   },
   "sideEffects": false,
diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json
index 2f16891f..c357c742 100644
--- a/packages/react/tsconfig.json
+++ b/packages/react/tsconfig.json
@@ -1,7 +1,10 @@
 {
   "extends": "../../tsconfig.json",
   "compilerOptions": {
-    "lib": ["DOM", "ES2020"],
+    "lib": [
+      "DOM",
+      "ES2021"
+    ],
     "outDir": "dist",
     "rootDir": "src",
     "jsx": "react",
diff --git a/packages/vue/package.json b/packages/vue/package.json
index 4b72d763..b38258e7 100644
--- a/packages/vue/package.json
+++ b/packages/vue/package.json
@@ -33,7 +33,7 @@
     "./package.json": "./package.json"
   },
   "scripts": {
-    "build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.js && esbuild src/index.ts --bundle --minify --sourcemap --target=es2019 --format=esm --outfile=dist/index.bundle.min.js",
+    "build": "tsc -p tsconfig.json && esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.js && esbuild src/index.ts --bundle --minify --sourcemap --target=es2017 --format=esm --outfile=dist/index.bundle.min.js",
     "watch": "tsc -p tsconfig.json -w --preserveWatchOutput & && esbuild src/index.ts --bundle --sourcemap --target=es2017 --format=esm --watch --outfile=dist/index.bundle.js &"
   },
   "sideEffects": false,
diff --git a/packages/vue/tsconfig.json b/packages/vue/tsconfig.json
index ca546457..db5dd490 100644
--- a/packages/vue/tsconfig.json
+++ b/packages/vue/tsconfig.json
@@ -1,7 +1,10 @@
 {
   "extends": "../../tsconfig.json",
   "compilerOptions": {
-    "lib": ["DOM", "ES2020"],
+    "lib": [
+      "DOM",
+      "ES2021"
+    ],
     "outDir": "dist",
     "rootDir": "src"
   },
diff --git a/tsconfig.json b/tsconfig.json
index dec5f010..c41ce413 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -7,7 +7,7 @@
     "forceConsistentCasingInFileNames": true,
     "isolatedModules": true,
     "lib": [
-      "ES2020",
+      "ES2021",
       "DOM"
     ],
     "module": "ESNext",