Repository: melt-ui/melt-ui
Pull request #918 (2024-01-15 18:10:03)

Refactor/withGet
This adds a `withGet` method, that overrides `writable`s set and update methods to update a local `value` variable, that can be accessed with `.get()`.

e.g.
```ts
const original = writable(1);
const awesome = withGet(original);

console.log(awesome.get()) // 1

awesome.set(2)
console.log(awesome.get()) // 2

original.set(3)
console.log(awesome.get()) // 3
```

It also works with `readable` and `derived` stores, but those currently require subscriptions, which then must be manually cleaned up. I'm working on improving this.

**TODO**
- [X] `withGet`
- [X] `withGet.writable`
- [x] `withGet.derived`


huntabyte: This is gonna be sick!! 

Patch:
diff --git a/src/docs/data/builders/date-field.ts b/src/docs/data/builders/date-field.ts
index fe56888a..639b452a 100644
--- a/src/docs/data/builders/date-field.ts
+++ b/src/docs/data/builders/date-field.ts
@@ -22,7 +22,7 @@ const dateFieldProps = [
 		name: 'onValueChange',
 		type: 'ChangeFn<DateValue | undefined>',
 		description:
-			'A function called when the value of the date field changes. It receives a single argument, which is an object containing `curr` and `prev` properties, whose values are the current and previous values of the value store. Whatever you return from this function will be set as the new value of the value store.',
+			'A function called when the value of the date field changes. It receives a single argument, which is an object containing `curr` and `next` properties, whose values are the current and previous values of the value store. Whatever you return from this function will be set as the new value of the value store.',
 	},
 	{
 		name: 'defaultPlaceholder',
@@ -41,7 +41,7 @@ const dateFieldProps = [
 		name: 'onPlaceholderChange',
 		type: 'ChangeFn<DateValue>',
 		description:
-			'A function called when the placeholder value changes. It receives a single argument, which is an object containing `curr` and `prev` properties, whose values are the current and previous values of the `placeholder` store. Whatever you return from this function will be set as the new value of the `placeholder` store.',
+			'A function called when the placeholder value changes. It receives a single argument, which is an object containing `curr` and `next` properties, whose values are the current and previous values of the `placeholder` store. Whatever you return from this function will be set as the new value of the `placeholder` store.',
 	},
 	{
 		name: 'isDateUnavailable',
diff --git a/src/docs/data/builders/slider.ts b/src/docs/data/builders/slider.ts
index a694e61e..06f9e5a6 100644
--- a/src/docs/data/builders/slider.ts
+++ b/src/docs/data/builders/slider.ts
@@ -56,13 +56,13 @@ const builder = builderSchema(BUILDER_NAME, {
 		},
 		{
 			name: 'value',
-			type: 'Writable<number>',
+			type: 'Writable<number[]>',
 			description: 'A writable store that can be used to update the slider value.',
 			see: SEE.BRING_YOUR_OWN_STORE,
 		},
 		{
 			name: 'onValueChange',
-			type: 'ChangeFn<number>',
+			type: 'ChangeFn<number[]>',
 			description: 'A callback that is called when the value of the slider changes.',
 			see: SEE.CHANGE_FUNCTIONS,
 		},
diff --git a/src/lib/builders/calendar/create.ts b/src/lib/builders/calendar/create.ts
index 42dd51f0..d6102212 100644
--- a/src/lib/builders/calendar/create.ts
+++ b/src/lib/builders/calendar/create.ts
@@ -3,43 +3,46 @@ import {
 	builder,
 	createElHelpers,
 	effect,
+	executeCallbacks,
 	generateIds,
 	isBrowser,
 	isHTMLElement,
+	isValidIndex,
 	kbd,
-	toWritableStores,
 	omit,
-	executeCallbacks,
-	styleToString,
 	overridable,
-	isValidIndex,
+	styleToString,
+	toWritableStores,
+	withGet,
 } from '$lib/internal/helpers/index.js';
 
-import { derived, get, writable } from 'svelte/store';
-import type { CalendarValue, CreateCalendarProps } from './types.js';
-import { tick } from 'svelte';
 import {
+	createFormatter,
 	createMonths,
+	dateStore,
 	getAnnouncer,
+	getDefaultDate,
+	getSelectableCells,
+	isAfter,
+	isBefore,
 	isCalendarCell,
 	parseStringToDateValue,
+	setPlaceholderToNodeValue,
 	toDate,
 	type Month,
-	isBefore,
-	isAfter,
-	getSelectableCells,
-	setPlaceholderToNodeValue,
 } from '$lib/internal/helpers/date/index.js';
+import type { MeltActionReturn } from '$lib/internal/types.js';
 import {
-	type DateValue,
 	getLocalTimeZone,
-	isToday,
-	isSameMonth,
 	isSameDay,
+	isSameMonth,
+	isToday,
+	type DateValue,
 } from '@internationalized/date';
-import { dateStore, createFormatter, getDefaultDate } from '$lib/internal/helpers/date/index.js';
-import type { MeltActionReturn } from '$lib/internal/types.js';
+import { tick } from 'svelte';
+import { derived, writable } from 'svelte/store';
 import type { CalendarEvents } from './events.js';
+import type { CalendarValue, CreateCalendarProps } from './types.js';
 
 const defaults = {
 	isDateDisabled: undefined,
@@ -116,14 +119,16 @@ export function createCalendar<
 	/**
 	 * A store containing the months to display in the calendar.
 	 */
-	const months = writable<Month<DateValue>[]>(
-		createMonths({
-			dateObj: get(placeholder),
-			weekStartsOn: withDefaults.weekStartsOn,
-			locale: withDefaults.locale,
-			fixedWeeks: withDefaults.fixedWeeks,
-			numberOfMonths: withDefaults.numberOfMonths,
-		})
+	const months = withGet(
+		writable<Month<DateValue>[]>(
+			createMonths({
+				dateObj: placeholder.get(),
+				weekStartsOn: withDefaults.weekStartsOn,
+				locale: withDefaults.locale,
+				fixedWeeks: withDefaults.fixedWeeks,
+				numberOfMonths: withDefaults.numberOfMonths,
+			})
+		)
 	);
 
 	/**
@@ -131,7 +136,7 @@ export function createCalendar<
 	 * which we use to determine how keyboard navigation and if we should apply
 	 * `data-outside-month` to cells.
 	 */
-	const visibleMonths = derived([months], ([$months]) => {
+	const visibleMonths = withGet.derived([months], ([$months]) => {
 		return $months.map((month) => {
 			return month.value;
 		});
@@ -143,7 +148,7 @@ export function createCalendar<
 		};
 	});
 
-	const isNextButtonDisabled = derived(
+	const isNextButtonDisabled = withGet.derived(
 		[months, maxValue, disabled],
 		([$months, $maxValue, $disabled]) => {
 			if (!$maxValue || !$months.length) return false;
@@ -154,7 +159,7 @@ export function createCalendar<
 		}
 	);
 
-	const isPrevButtonDisabled = derived(
+	const isPrevButtonDisabled = withGet.derived(
 		[months, minValue, disabled],
 		([$months, $minValue, $disabled]) => {
 			if (!$minValue || !$months.length) return false;
@@ -169,7 +174,7 @@ export function createCalendar<
 	 * A derived store function that determines if a date is disabled based
 	 * on the `isDateDisabled` prop, `minValue`, and `maxValue` props.
 	 */
-	const isDateDisabled = derived(
+	const isDateDisabled = withGet.derived(
 		[options.isDateDisabled, minValue, maxValue, disabled],
 		([$isDateDisabled, $minValue, $maxValue, $disabled]) => {
 			return (date: DateValue) => {
@@ -230,7 +235,7 @@ export function createCalendar<
 	 * This value updates automatically as the user navigates the calendar, even when
 	 * displaying multiple months using the `numberOfMonths` prop.
 	 */
-	const headingValue = derived([months, locale], ([$months, $locale]) => {
+	const headingValue = withGet.derived([months, locale], ([$months, $locale]) => {
 		if (!$months.length) return '';
 		if ($locale !== formatter.getLocale()) {
 			formatter.setLocale($locale);
@@ -260,7 +265,7 @@ export function createCalendar<
 	 * The accessible heading label for the calendar, generated by combining the `calendarLabel`
 	 * prop and the `headingValue` store to create a label like `Event Date, January 2021`.
 	 */
-	const fullCalendarLabel = derived(
+	const fullCalendarLabel = withGet.derived(
 		[headingValue, calendarLabel],
 		([$headingValue, $calendarLabel]) => {
 			return `${$calendarLabel}, ${$headingValue}`;
@@ -289,7 +294,7 @@ export function createCalendar<
 			 * The label is dynamically updated through an effect whenever there
 			 * are changes in the active date or label.
 			 */
-			createAccessibleHeading(node, get(fullCalendarLabel));
+			createAccessibleHeading(node, fullCalendarLabel.get());
 			announcer = getAnnouncer();
 
 			const unsubKb = addMeltEventListener(node, 'keydown', handleCalendarKeydown);
@@ -364,7 +369,7 @@ export function createCalendar<
 		action: (node: HTMLElement): MeltActionReturn<CalendarEvents['prevButton']> => {
 			const unsub = executeCallbacks(
 				addMeltEventListener(node, 'click', () => {
-					if (get(isPrevButtonDisabled)) return;
+					if (isPrevButtonDisabled.get()) return;
 					prevPage();
 				})
 			);
@@ -395,7 +400,7 @@ export function createCalendar<
 		action: (node: HTMLElement): MeltActionReturn<CalendarEvents['nextButton']> => {
 			const unsub = executeCallbacks(
 				addMeltEventListener(node, 'click', () => {
-					if (get(isNextButtonDisabled)) return;
+					if (isNextButtonDisabled.get()) return;
 					nextPage();
 				})
 			);
@@ -484,7 +489,7 @@ export function createCalendar<
 					const args = getElArgs();
 					if (args.disabled) return;
 					if (!args.value) return;
-					handleCellClick(parseStringToDateValue(args.value, get(placeholder)));
+					handleCellClick(parseStringToDateValue(args.value, placeholder.get()));
 				})
 			);
 
@@ -512,7 +517,7 @@ export function createCalendar<
 		([$placeholder, $weekStartsOn, $locale, $fixedWeeks, $numberOfMonths]) => {
 			if (!isBrowser || !$placeholder) return;
 
-			const $visibleMonths = get(visibleMonths);
+			const $visibleMonths = visibleMonths.get();
 
 			/**
 			 * If the placeholder's month is already in the visible months,
@@ -544,7 +549,7 @@ export function createCalendar<
 	 */
 	effect([fullCalendarLabel], ([$fullCalendarLabel]) => {
 		if (!isBrowser) return;
-		const node = document.getElementById(get(ids.accessibleHeading));
+		const node = document.getElementById(ids.accessibleHeading.get());
 		if (!isHTMLElement(node)) return;
 		node.textContent = $fullCalendarLabel;
 	});
@@ -555,10 +560,10 @@ export function createCalendar<
 	effect([value], ([$value]) => {
 		if (Array.isArray($value) && $value.length) {
 			const lastValue = $value[$value.length - 1];
-			if (lastValue && get(placeholder) !== lastValue) {
+			if (lastValue && placeholder.get() !== lastValue) {
 				placeholder.set(lastValue);
 			}
-		} else if (!Array.isArray($value) && $value && get(placeholder) !== $value) {
+		} else if (!Array.isArray($value) && $value && placeholder.get() !== $value) {
 			placeholder.set($value);
 		}
 	});
@@ -645,7 +650,7 @@ export function createCalendar<
 		});
 		const h2 = document.createElement('div');
 		h2.textContent = label;
-		h2.id = get(ids.accessibleHeading);
+		h2.id = ids.accessibleHeading.get();
 		h2.role = 'heading';
 		h2.ariaLevel = '2';
 		node.insertBefore(div, node.firstChild);
@@ -672,18 +677,18 @@ export function createCalendar<
 	 * ```
 	 */
 	function nextPage() {
-		const $months = get(months);
-		const $numberOfMonths = get(numberOfMonths);
-		if (get(pagedNavigation)) {
+		const $months = months.get();
+		const $numberOfMonths = numberOfMonths.get();
+		if (pagedNavigation.get()) {
 			const firstMonth = $months[0].value;
 			placeholder.set(firstMonth.add({ months: $numberOfMonths }));
 		} else {
 			const firstMonth = $months[0].value;
 			const newMonths = createMonths({
 				dateObj: firstMonth.add({ months: 1 }),
-				weekStartsOn: get(weekStartsOn),
-				locale: get(locale),
-				fixedWeeks: get(fixedWeeks),
+				weekStartsOn: weekStartsOn.get(),
+				locale: locale.get(),
+				fixedWeeks: fixedWeeks.get(),
 				numberOfMonths: $numberOfMonths,
 			});
 
@@ -713,18 +718,18 @@ export function createCalendar<
 	 * ```
 	 */
 	function prevPage() {
-		const $months = get(months);
-		const $numberOfMonths = get(numberOfMonths);
-		if (get(pagedNavigation)) {
+		const $months = months.get();
+		const $numberOfMonths = numberOfMonths.get();
+		if (pagedNavigation.get()) {
 			const firstMonth = $months[0].value;
 			placeholder.set(firstMonth.subtract({ months: $numberOfMonths }));
 		} else {
 			const firstMonth = $months[0].value;
 			const newMonths = createMonths({
 				dateObj: firstMonth.subtract({ months: 1 }),
-				weekStartsOn: get(weekStartsOn),
-				locale: get(locale),
-				fixedWeeks: get(fixedWeeks),
+				weekStartsOn: weekStartsOn.get(),
+				locale: locale.get(),
+				fixedWeeks: fixedWeeks.get(),
 				numberOfMonths: $numberOfMonths,
 			});
 
@@ -839,14 +844,14 @@ export function createCalendar<
 	}
 
 	function handleCellClick(date: DateValue) {
-		const $readonly = get(readonly);
+		const $readonly = readonly.get();
 		if ($readonly) return;
-		const $isDateDisabled = get(isDateDisabled);
-		const $isUnavailable = get(options.isDateUnavailable);
+		const $isDateDisabled = isDateDisabled.get();
+		const $isUnavailable = options.isDateUnavailable.get();
 		if ($isDateDisabled?.(date) || $isUnavailable?.(date)) return;
 
 		value.update((prev) => {
-			const $multiple = get(multiple);
+			const $multiple = multiple.get();
 			if ($multiple) {
 				return handleMultipleUpdate(prev, date) as S;
 			} else {
@@ -864,7 +869,7 @@ export function createCalendar<
 	function handleSingleUpdate(prev: S | undefined, date: DateValue) {
 		if (Array.isArray(prev)) throw new Error('Invalid value for multiple prop.');
 		if (!prev) return date;
-		const $preventDeselect = get(preventDeselect);
+		const $preventDeselect = preventDeselect.get();
 		if (!$preventDeselect && isSameDay(prev, date)) {
 			placeholder.set(date);
 			return undefined;
@@ -876,7 +881,7 @@ export function createCalendar<
 		if (!prev) return [date];
 		if (!Array.isArray(prev)) throw new Error('Invalid value for multiple prop.');
 		const index = prev.findIndex((d) => isSameDay(d, date));
-		const $preventDeselect = get(preventDeselect);
+		const $preventDeselect = preventDeselect.get();
 
 		if (index === -1) {
 			return [...prev, date];
@@ -919,12 +924,12 @@ export function createCalendar<
 			const cellValue = currentCell.getAttribute('data-value');
 			if (!cellValue) return;
 
-			handleCellClick(parseStringToDateValue(cellValue, get(placeholder)));
+			handleCellClick(parseStringToDateValue(cellValue, placeholder.get()));
 		}
 	}
 
 	function shiftFocus(node: HTMLElement, add: number) {
-		const candidateCells = getSelectableCells(get(ids.calendar));
+		const candidateCells = getSelectableCells(ids.calendar.get());
 		if (!candidateCells.length) return;
 
 		const index = candidateCells.indexOf(node);
@@ -955,17 +960,17 @@ export function createCalendar<
 			 */
 
 			// shift the calendar back a month unless previous month is disabled
-			if (get(isPrevButtonDisabled)) return;
+			if (isPrevButtonDisabled.get()) return;
 
-			const $months = get(months);
+			const $months = months.get();
 			const firstMonth = $months[0].value;
-			const $numberOfMonths = get(numberOfMonths);
+			const $numberOfMonths = numberOfMonths.get();
 			placeholder.set(firstMonth.subtract({ months: $numberOfMonths }));
 
 			// Without a tick here, it seems to be too fast for
 			// the DOM to update, with the tick it works great
 			tick().then(() => {
-				const newCandidateCells = getSelectableCells(get(ids.calendar));
+				const newCandidateCells = getSelectableCells(ids.calendar.get());
 				if (!newCandidateCells.length) {
 					return;
 				}
@@ -994,15 +999,15 @@ export function createCalendar<
 			 */
 
 			// shift the calendar forward a month unless next month is disabled
-			if (get(isNextButtonDisabled)) return;
+			if (isNextButtonDisabled.get()) return;
 
-			const $months = get(months);
+			const $months = months.get();
 			const firstMonth = $months[0].value;
-			const $numberOfMonths = get(numberOfMonths);
+			const $numberOfMonths = numberOfMonths.get();
 			placeholder.set(firstMonth.add({ months: $numberOfMonths }));
 
 			tick().then(() => {
-				const newCandidateCells = getSelectableCells(get(ids.calendar));
+				const newCandidateCells = getSelectableCells(ids.calendar.get());
 				if (!newCandidateCells.length) {
 					return;
 				}
diff --git a/src/lib/builders/context-menu/create.ts b/src/lib/builders/context-menu/create.ts
index 47a61232..dd4a7b5f 100644
--- a/src/lib/builders/context-menu/create.ts
+++ b/src/lib/builders/context-menu/create.ts
@@ -5,7 +5,6 @@ import {
 	builder,
 	createElHelpers,
 	derivedVisible,
-	derivedWithUnsubscribe,
 	effect,
 	executeCallbacks,
 	getNextFocusable,
@@ -19,11 +18,13 @@ import {
 	overridable,
 	styleToString,
 	toWritableStores,
+	withGet,
+	type WithGet,
 } from '$lib/internal/helpers/index.js';
 import type { MeltActionReturn } from '$lib/internal/types.js';
 import type { VirtualElement } from '@floating-ui/core';
 import { tick } from 'svelte';
-import { get, writable, type Readable } from 'svelte/store';
+import { derived, writable, type Readable } from 'svelte/store';
 import {
 	applyAttrsIfDisabled,
 	clearTimerStore,
@@ -32,8 +33,8 @@ import {
 	handleMenuNavigation,
 	handleTabNavigation,
 	setMeltMenuAttribute,
-	type _MenuParts,
 	type Point,
+	type _MenuParts,
 } from '../menu/index.js';
 import type { ContextMenuEvents } from './events.js';
 import type { CreateContextMenuProps } from './types.js';
@@ -70,8 +71,8 @@ export function createContextMenu(props?: CreateContextMenuProps) {
 	const openWritable = withDefaults.open ?? writable(withDefaults.defaultOpen);
 	const rootOpen = overridable(openWritable, withDefaults?.onOpenChange);
 	const rootActiveTrigger = writable<HTMLElement | null>(null);
-	const nextFocusable = writable<HTMLElement | null>(null);
-	const prevFocusable = writable<HTMLElement | null>(null);
+	const nextFocusable = withGet.writable<HTMLElement | null>(null);
+	const prevFocusable = withGet.writable<HTMLElement | null>(null);
 
 	const {
 		item,
@@ -86,38 +87,40 @@ export function createContextMenu(props?: CreateContextMenuProps) {
 		groupLabel,
 	} = createMenuBuilder({
 		rootOpen,
-		rootActiveTrigger,
 		rootOptions,
-		nextFocusable,
-		prevFocusable,
+		rootActiveTrigger: withGet(rootActiveTrigger),
+		nextFocusable: withGet(nextFocusable),
+		prevFocusable: withGet(prevFocusable),
 		selector: 'context-menu',
 		removeScroll: true,
 		ids: withDefaults.ids,
 	});
 
 	const point = writable<Point | null>(null);
-	const virtual: Readable<VirtualElement | null> = derivedWithUnsubscribe([point], ([$point]) => {
-		if ($point === null) return null;
+	const virtual: WithGet<Readable<VirtualElement | null>> = withGet(
+		derived([point], ([$point]) => {
+			if ($point === null) return null;
 
-		return {
-			getBoundingClientRect: () =>
-				DOMRect.fromRect({
-					width: 0,
-					height: 0,
-					...$point,
-				}),
-		};
-	});
-	const longPressTimer = writable(0);
+			return {
+				getBoundingClientRect: () =>
+					DOMRect.fromRect({
+						width: 0,
+						height: 0,
+						...$point,
+					}),
+			};
+		})
+	);
+	const longPressTimer = withGet.writable(0);
 
 	function handleClickOutside(e: PointerEvent) {
-		get(rootOptions.onOutsideClick)?.(e);
+		rootOptions.onOutsideClick.get()?.(e);
 		if (e.defaultPrevented) return;
 
 		const target = e.target;
 		if (!(target instanceof Element)) return;
 
-		const isClickInsideTrigger = target.closest(`[data-id="${get(ids.trigger)}"]`) !== null;
+		const isClickInsideTrigger = target.closest(`[data-id="${ids.trigger.get()}"]`) !== null;
 
 		if (!isClickInsideTrigger || isLeftClick(e)) {
 			rootOpen.set(false);
@@ -165,7 +168,7 @@ export function createContextMenu(props?: CreateContextMenuProps) {
 					if (!$isVisible || !$rootActiveTrigger) return;
 					tick().then(() => {
 						setMeltMenuAttribute(node, selector);
-						const $virtual = get(virtual);
+						const $virtual = virtual.get();
 						const popper = usePopper(node, {
 							anchorElement: $virtual ? $virtual : $rootActiveTrigger,
 							open: rootOpen,
@@ -199,7 +202,7 @@ export function createContextMenu(props?: CreateContextMenuProps) {
 					const isKeyDownInside = target.closest("[role='menu']") === menuEl;
 					if (!isKeyDownInside) return;
 					if (FIRST_LAST_KEYS.includes(e.key)) {
-						handleMenuNavigation(e, get(loop));
+						handleMenuNavigation(e, loop.get());
 					}
 
 					/**
diff --git a/src/lib/builders/date-field/create.ts b/src/lib/builders/date-field/create.ts
index c5a92aa5..0d82fd3c 100644
--- a/src/lib/builders/date-field/create.ts
+++ b/src/lib/builders/date-field/create.ts
@@ -1,68 +1,67 @@
-import type { CreateDateFieldProps } from './types';
 import {
+	createFormatter,
+	dateStore,
+	getAnnouncer,
+	getDaysInMonth,
+	getDefaultDate,
+	getFirstSegment,
+	handleSegmentNavigation,
+	isBefore,
+	isSegmentNavigationKey,
+	moveToNextSegment,
+	toDate,
+} from '$lib/internal/helpers/date/index.js';
+import {
+	addMeltEventListener,
 	builder,
 	createElHelpers,
 	effect,
-	kbd,
-	overridable,
-	toWritableStores,
-	omit,
-	isHTMLElement,
-	addMeltEventListener,
 	executeCallbacks,
+	isHTMLElement,
 	isNumberString,
-	styleToString,
+	kbd,
 	noop,
+	omit,
+	overridable,
 	sleep,
+	styleToString,
+	toWritableStores,
+	withGet,
 } from '$lib/internal/helpers/index.js';
+import type { MeltActionReturn } from '$lib/internal/types';
+import type { DateValue } from '@internationalized/date';
+import { derived, writable, type Updater } from 'svelte/store';
+import { generateIds } from '../../internal/helpers/id';
 import {
-	dateStore,
-	getDaysInMonth,
-	getDefaultDate,
-	toDate,
-	createFormatter,
-	getAnnouncer,
-	isBefore,
-	getFirstSegment,
-} from '$lib/internal/helpers/date/index.js';
-import { derived, get, writable, type Updater } from 'svelte/store';
-import {
-	isFirstSegment,
 	areAllSegmentsFilled,
 	createContent,
+	getPartFromNode,
 	getValueFromSegments,
+	inferGranularity,
 	initSegmentStates,
 	initializeSegmentValues,
+	isAcceptableSegmentKey,
 	isDateAndTimeSegmentObj,
 	isDateSegmentPart,
-	getPartFromNode,
-	isAcceptableSegmentKey,
+	isFirstSegment,
 	removeDescriptionElement,
-	syncSegmentValues,
 	setDescription,
-	inferGranularity,
+	syncSegmentValues,
 } from './_internal/helpers.js';
-import {
-	handleSegmentNavigation,
-	isSegmentNavigationKey,
-	moveToNextSegment,
-} from '$lib/internal/helpers/date/index.js';
 import type {
 	AnyExceptLiteral,
-	SegmentPart,
 	DateAndTimeSegmentObj,
 	DateSegmentObj,
 	DateSegmentPart,
 	DayPeriod,
 	SegmentAttrProps,
 	SegmentBuilders,
+	SegmentPart,
 	TimeSegmentObj,
 	TimeSegmentPart,
 } from './_internal/types.js';
-import type { DateValue } from '@internationalized/date';
-import type { MeltActionReturn } from '$lib/internal/types';
 import type { DateFieldEvents } from './events';
-import { generateIds } from '../../internal/helpers/id';
+import type { CreateDateFieldProps } from './types';
 
 const defaults = {
 	isDateUnavailable: undefined,
@@ -146,7 +145,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 		withDefaults.defaultPlaceholder ?? defaultDate
 	);
 
-	const inferredGranularity = derived(
+	const inferredGranularity = withGet.derived(
 		[placeholder, granularity],
 		([$placeholder, $granularity]) => {
 			if ($granularity) {
@@ -157,9 +156,9 @@ export function createDateField(props?: CreateDateFieldProps) {
 		}
 	);
 
-	const formatter = createFormatter(get(locale));
-	const initialSegments = initializeSegmentValues(get(inferredGranularity));
-	const segmentValues = writable(structuredClone(initialSegments));
+	const formatter = createFormatter(locale.get());
+	const initialSegments = initializeSegmentValues(inferredGranularity.get());
+	const segmentValues = withGet.writable(structuredClone(initialSegments));
 
 	let announcer = getAnnouncer();
 
@@ -170,9 +169,8 @@ export function createDateField(props?: CreateDateFieldProps) {
 	 */
 	const updatingDayPeriod = writable<DayPeriod>(null);
 
-	const readonlySegmentsSet = derived(
-		readonlySegments,
-		($readonlySegments) => new Set<SegmentPart>($readonlySegments)
+	const readonlySegmentsSet = withGet(
+		derived(readonlySegments, ($readonlySegments) => new Set<SegmentPart>($readonlySegments))
 	);
 
 	const ids = toWritableStores({ ...generateIds(dateFieldIdParts), ...withDefaults.ids });
@@ -250,7 +248,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 				formatter,
 				locale: $locale,
 				granularity: $inferredGranularity,
-				dateRef: get(placeholder),
+				dateRef: placeholder.get(),
 				hideTimeZone: $hideTimeZone,
 				hourCycle: $hourCycle,
 			});
@@ -279,7 +277,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 		action: (node: HTMLElement) => {
 			const unsub = executeCallbacks(
 				addMeltEventListener(node, 'click', () => {
-					const firstSegment = getFirstSegment(get(ids.field));
+					const firstSegment = getFirstSegment(ids.field.get());
 					if (!firstSegment) return;
 					sleep(1).then(() => firstSegment.focus());
 				}),
@@ -377,7 +375,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 
 			return {
 				destroy() {
-					removeDescriptionElement(get(ids.description));
+					removeDescriptionElement(ids.description.get());
 				},
 			};
 		},
@@ -495,9 +493,9 @@ export function createDateField(props?: CreateDateFieldProps) {
 			? Updater<TimeSegmentObj[T]>
 			: Updater<DateAndTimeSegmentObj[T]>
 	) {
-		if (get(disabled) || get(readonly) || get(readonlySegmentsSet).has(part)) return;
+		if (disabled.get() || readonly.get() || readonlySegmentsSet.get().has(part)) return;
 		segmentValues.update((prev) => {
-			const dateRef = get(placeholder);
+			const dateRef = placeholder.get();
 			if (isDateAndTimeSegmentObj(prev)) {
 				const pVal = prev[part];
 				const castCb = cb as Updater<DateAndTimeSegmentObj[T]>;
@@ -517,7 +515,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 				} else if (part === 'dayPeriod') {
 					const next = castCb(pVal) as DateAndTimeSegmentObj['dayPeriod'];
 					updatingDayPeriod.set(next);
-					const date = get(placeholder);
+					const date = placeholder.get();
 					if ('hour' in date) {
 						const trueHour = date.hour;
 						if (next === 'AM') {
@@ -573,14 +571,14 @@ export function createDateField(props?: CreateDateFieldProps) {
 
 			return prev;
 		});
-		const $segmentValues = get(segmentValues);
-		const $fieldId = get(ids.field);
+		const $segmentValues = segmentValues.get();
+		const $fieldId = ids.field.get();
 		if (areAllSegmentsFilled($segmentValues, $fieldId)) {
 			value.set(
 				getValueFromSegments({
 					segmentObj: $segmentValues,
 					id: $fieldId,
-					dateRef: get(placeholder),
+					dateRef: placeholder.get(),
 				})
 			);
 			updatingDayPeriod.set(null);
@@ -597,7 +595,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 	 * the handlers.
 	 */
 	function handleSegmentKeydown(e: KeyboardEvent, part: AnyExceptLiteral) {
-		const $disabled = get(disabled);
+		const $disabled = disabled.get();
 		if (e.key !== kbd.TAB) {
 			e.preventDefault();
 		}
@@ -622,7 +620,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 	 * focusing the segment if the field is disabled.
 	 */
 	function handleSegmentClick(e: MouseEvent) {
-		const $disabled = get(disabled);
+		const $disabled = disabled.get();
 		if ($disabled) {
 			e.preventDefault();
 			return;
@@ -677,8 +675,8 @@ export function createDateField(props?: CreateDateFieldProps) {
 			return;
 		}
 
-		const $segmentMonthValue = get(segmentValues).month;
-		const $placeholder = get(placeholder);
+		const $segmentMonthValue = segmentValues.get().month;
+		const $placeholder = placeholder.get();
 
 		const daysInMonth = $segmentMonthValue
 			? getDaysInMonth($placeholder.set({ month: $segmentMonthValue }))
@@ -711,7 +709,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 			return;
 		}
 
-		const $fieldId = get(ids.field);
+		const $fieldId = ids.field.get();
 
 		if (isNumberString(e.key)) {
 			const num = parseInt(e.key);
@@ -865,7 +863,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 			return;
 		}
 
-		const $placeholder = get(placeholder);
+		const $placeholder = placeholder.get();
 		function getMonthAnnouncement(month: number) {
 			return `${month} - ${formatter.fullMonth(toDate($placeholder.set({ month })))}`;
 		}
@@ -900,7 +898,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 			});
 			return;
 		}
-		const $fieldId = get(ids.field);
+		const $fieldId = ids.field.get();
 
 		if (isNumberString(e.key)) {
 			const num = parseInt(e.key);
@@ -1052,7 +1050,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 		}
 
 		states.year.hasTouched = true;
-		const $placeholder = get(placeholder);
+		const $placeholder = placeholder.get();
 
 		if (e.key === kbd.ARROW_UP) {
 			updateSegment('year', (prev) => {
@@ -1081,7 +1079,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 			return;
 		}
 
-		const $fieldId = get(ids.field);
+		const $fieldId = ids.field.get();
 
 		if (isNumberString(e.key)) {
 			let moveToNext = false;
@@ -1181,14 +1179,14 @@ export function createDateField(props?: CreateDateFieldProps) {
 	}
 
 	function handleHourSegmentKeydown(e: KeyboardEvent) {
-		const dateRef = get(placeholder);
+		const dateRef = placeholder.get();
 		if (!isAcceptableSegmentKey(e.key) || !('hour' in dateRef)) {
 			return;
 		}
 
 		states.hour.hasTouched = true;
 
-		const $hourCycle = get(hourCycle);
+		const $hourCycle = hourCycle.get();
 
 		if (e.key === kbd.ARROW_UP) {
 			updateSegment('hour', (prev) => {
@@ -1217,7 +1215,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 			return;
 		}
 
-		const $fieldId = get(ids.field);
+		const $fieldId = ids.field.get();
 
 		if (isNumberString(e.key)) {
 			const num = parseInt(e.key);
@@ -1366,7 +1364,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 	}
 
 	function handleMinuteSegmentKeydown(e: KeyboardEvent) {
-		const dateRef = get(placeholder);
+		const dateRef = placeholder.get();
 		if (!isAcceptableSegmentKey(e.key) || !('minute' in dateRef)) {
 			return;
 		}
@@ -1401,7 +1399,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 			return;
 		}
 
-		const $fieldId = get(ids.field);
+		const $fieldId = ids.field.get();
 
 		if (isNumberString(e.key)) {
 			const num = parseInt(e.key);
@@ -1550,7 +1548,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 	}
 
 	function handleSecondSegmentKeydown(e: KeyboardEvent) {
-		const dateRef = get(placeholder);
+		const dateRef = placeholder.get();
 		if (!isAcceptableSegmentKey(e.key)) {
 			return;
 		}
@@ -1586,7 +1584,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 			return;
 		}
 
-		const $fieldId = get(ids.field);
+		const $fieldId = ids.field.get();
 
 		if (isNumberString(e.key)) {
 			const num = parseInt(e.key);
@@ -1779,7 +1777,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 		}
 
 		if (isSegmentNavigationKey(e.key)) {
-			handleSegmentNavigation(e, get(ids.field));
+			handleSegmentNavigation(e, ids.field.get());
 		}
 	}
 
@@ -1837,7 +1835,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 
 	function handleTimeZoneSegmentKeydown(e: KeyboardEvent) {
 		if (isSegmentNavigationKey(e.key)) {
-			handleSegmentNavigation(e, get(ids.field));
+			handleSegmentNavigation(e, ids.field.get());
 		}
 	}
 
@@ -1857,7 +1855,7 @@ export function createDateField(props?: CreateDateFieldProps) {
 	 * Gets the `aria-labelledby` value for a given segment part.
 	 */
 	function getLabelledBy(part: AnyExceptLiteral) {
-		return `${get(ids[part])} ${get(ids.label)}`;
+		return `${ids[part].get()} ${ids.label.get()}`;
 	}
 
 	/**
@@ -1872,9 +1870,9 @@ export function createDateField(props?: CreateDateFieldProps) {
 	effect(value, ($value) => {
 		if ($value) {
 			// Set the description of the field for screen readers
-			setDescription(get(ids.description), formatter, $value);
+			setDescription(ids.description.get(), formatter, $value);
 		}
-		if ($value && get(placeholder) !== $value) {
+		if ($value && placeholder.get() !== $value) {
 			placeholder.set($value);
 		}
 	});
diff --git a/src/lib/builders/date-picker/create.ts b/src/lib/builders/date-picker/create.ts
index 16f21a86..9efb5e82 100644
--- a/src/lib/builders/date-picker/create.ts
+++ b/src/lib/builders/date-picker/create.ts
@@ -1,20 +1,19 @@
-import {
-	effect,
-	toWritableStores,
-	omit,
-	builder,
-	addMeltEventListener,
-} from '$lib/internal/helpers/index.js';
-import { get } from 'svelte/store';
 import { createCalendar, createDateField, createPopover } from '$lib/builders/index.js';
-import type { CreateDatePickerProps } from './types.js';
 import {
 	handleSegmentNavigation,
 	isSegmentNavigationKey,
 } from '$lib/internal/helpers/date/index.js';
+import {
+	addMeltEventListener,
+	builder,
+	effect,
+	omit,
+	toWritableStores,
+} from '$lib/internal/helpers/index.js';
+import type { CreateDatePickerProps } from './types.js';
 
-import { dateStore, createFormatter, getDefaultDate } from '$lib/internal/helpers/date/index.js';
 import { pickerOpenFocus } from '$lib/internal/helpers/date/focus.js';
+import { createFormatter, dateStore, getDefaultDate } from '$lib/internal/helpers/date/index.js';
 import type { MeltActionReturn } from '$lib/internal/types.js';
 import type { DatePickerEvents } from './events.js';
 
@@ -98,7 +97,7 @@ export function createDatePicker(props?: CreateDatePickerProps) {
 			};
 		},
 	});
-	const formatter = createFormatter(get(options.locale));
+	const formatter = createFormatter(options.locale.get());
 
 	effect([options.locale], ([$locale]) => {
 		dateField.options.locale.set($locale);
@@ -162,7 +161,7 @@ export function createDatePicker(props?: CreateDatePickerProps) {
 
 	effect([open], ([$open]) => {
 		if (!$open) {
-			const $value = get(value);
+			const $value = value.get();
 			if ($value) {
 				placeholder.set($value);
 			} else {
@@ -174,7 +173,7 @@ export function createDatePicker(props?: CreateDatePickerProps) {
 	function handleTriggerKeydown(e: KeyboardEvent) {
 		if (isSegmentNavigationKey(e.key)) {
 			e.preventDefault();
-			handleSegmentNavigation(e, get(dateField.ids.field));
+			handleSegmentNavigation(e, dateField.ids.field.get());
 		}
 	}
 
diff --git a/src/lib/builders/date-range-field/create.ts b/src/lib/builders/date-range-field/create.ts
index d0f21f76..3c529643 100644
--- a/src/lib/builders/date-range-field/create.ts
+++ b/src/lib/builders/date-range-field/create.ts
@@ -1,29 +1,30 @@
-import type { CreateDateRangeFieldProps } from './types.js';
+import { createDateField } from '$lib/index.js';
 import {
+	areAllDaysBetweenValid,
+	dateStore,
+	getAnnouncer,
+	getDefaultDate,
+	getFirstSegment,
+	isBefore,
+} from '$lib/internal/helpers/date/index.js';
+import {
+	addMeltEventListener,
 	builder,
 	createElHelpers,
-	overridable,
-	toWritableStores,
-	omit,
 	effect,
-	styleToString,
 	executeCallbacks,
-	addMeltEventListener,
+	omit,
+	overridable,
 	sleep,
+	styleToString,
+	toWritableStores,
 } from '$lib/internal/helpers/index.js';
-import {
-	dateStore,
-	getDefaultDate,
-	getAnnouncer,
-	isBefore,
-	areAllDaysBetweenValid,
-	getFirstSegment,
-} from '$lib/internal/helpers/date/index.js';
-import { derived, get, writable } from 'svelte/store';
-import { removeDescriptionElement } from './_internal/helpers.js';
-import { createDateField } from '$lib/index.js';
 import type { DateValue } from '@internationalized/date';
+import { derived, writable } from 'svelte/store';
 import { generateIds } from '../../internal/helpers/id';
+import { removeDescriptionElement } from './_internal/helpers.js';
+import type { CreateDateRangeFieldProps } from './types.js';
+import { withGet } from '$lib/internal/helpers/withGet';
 
 const defaults = {
 	isDateUnavailable: undefined,
@@ -68,12 +69,12 @@ export function createDateRangeField(props?: CreateDateRangeFieldProps) {
 	const valueWritable = withDefaults.value ?? writable(withDefaults.defaultValue);
 	const value = overridable(valueWritable, withDefaults.onValueChange);
 
-	const defaultStart = withDefaults.value ? get(withDefaults.value)?.start : undefined;
-	const startValue = writable<DateValue | undefined>(
-		defaultStart ?? withDefaults.defaultValue?.start
+	const startValue = withGet.writable<DateValue | undefined>(
+		value.get()?.start ?? withDefaults.defaultValue?.start
+	);
+	const endValue = withGet.writable<DateValue | undefined>(
+		value.get()?.end ?? withDefaults.defaultValue?.end
 	);
-	const defaultEnd = withDefaults.value ? get(withDefaults.value)?.end : undefined;
-	const endValue = writable<DateValue | undefined>(defaultEnd ?? withDefaults.defaultValue?.end);
 
 	const isCompleted = derived(value, ($value) => {
 		return $value?.start && $value?.end;
@@ -185,7 +186,7 @@ export function createDateRangeField(props?: CreateDateRangeFieldProps) {
 		action: (node: HTMLElement) => {
 			const unsub = executeCallbacks(
 				addMeltEventListener(node, 'click', () => {
-					const firstSegment = getFirstSegment(get(ids.field));
+					const firstSegment = getFirstSegment(ids.field.get());
 					if (!firstSegment) return;
 					sleep(1).then(() => firstSegment.focus());
 				}),
@@ -233,7 +234,7 @@ export function createDateRangeField(props?: CreateDateRangeFieldProps) {
 			getAnnouncer();
 			return {
 				destroy() {
-					removeDescriptionElement(get(ids.description));
+					removeDescriptionElement(ids.description.get());
 				},
 			};
 		},
@@ -287,8 +288,8 @@ export function createDateRangeField(props?: CreateDateRangeFieldProps) {
 	 */
 
 	effect([value], ([$value]) => {
-		const $startValue = get(startValue);
-		const $endValue = get(endValue);
+		const $startValue = startValue.get();
+		const $endValue = endValue.get();
 
 		if ($value?.start && $value?.end) {
 			if ($value.start !== $startValue) {
@@ -302,7 +303,7 @@ export function createDateRangeField(props?: CreateDateRangeFieldProps) {
 	});
 
 	effect([startValue, endValue], ([$startValue, $endValue]) => {
-		const $value = get(value);
+		const $value = value.get();
 
 		if ($value && $value?.start === $startValue && $value?.end === $endValue) return;
 
diff --git a/src/lib/builders/date-range-picker/create.ts b/src/lib/builders/date-range-picker/create.ts
index d704966b..c1e73c6c 100644
--- a/src/lib/builders/date-range-picker/create.ts
+++ b/src/lib/builders/date-range-picker/create.ts
@@ -1,22 +1,21 @@
+import { createPopover, createRangeCalendar } from '$lib/builders/index.js';
 import {
+	handleSegmentNavigation,
+	isSegmentNavigationKey,
+} from '$lib/internal/helpers/date/index.js';
+import {
+	addMeltEventListener,
+	builder,
 	effect,
-	toWritableStores,
 	omit,
-	builder,
-	addMeltEventListener,
+	toWritableStores,
 } from '$lib/internal/helpers/index.js';
-import { get } from 'svelte/store';
-import { createRangeCalendar, createPopover } from '$lib/builders/index.js';
 import type { CreateDateRangePickerProps } from './types.js';
-import {
-	handleSegmentNavigation,
-	isSegmentNavigationKey,
-} from '$lib/internal/helpers/date/index.js';
 
-import { dateStore, createFormatter, getDefaultDate } from '$lib/internal/helpers/date/index.js';
-import { createDateRangeField } from '../date-range-field/create.js';
 import { pickerOpenFocus } from '$lib/internal/helpers/date/focus.js';
+import { createFormatter, dateStore, getDefaultDate } from '$lib/internal/helpers/date/index.js';
 import type { MeltActionReturn } from '$lib/internal/types.js';
+import { createDateRangeField } from '../date-range-field/create.js';
 import type { DateRangePickerEvents } from './events.js';
 
 const defaults = {
@@ -84,7 +83,7 @@ export function createDateRangePicker(props?: CreateDateRangePickerProps) {
 		granularity: withDefaults.granularity,
 	});
 
-	const formatter = createFormatter(get(locale));
+	const formatter = createFormatter(locale.get());
 
 	const placeholder = dateStore(rfPlaceholder, withDefaults.defaultPlaceholder ?? defaultDate);
 
@@ -144,7 +143,7 @@ export function createDateRangePicker(props?: CreateDateRangePickerProps) {
 
 	effect([popover.states.open], ([$open]) => {
 		if (!$open) {
-			const $value = get(value);
+			const $value = value.get();
 			if ($value?.start) {
 				placeholder.set($value.start);
 			} else {
@@ -178,7 +177,7 @@ export function createDateRangePicker(props?: CreateDateRangePickerProps) {
 	function handleTriggerKeydown(e: KeyboardEvent) {
 		if (isSegmentNavigationKey(e.key)) {
 			e.preventDefault();
-			handleSegmentNavigation(e, get(rangeField.ids.field.field));
+			handleSegmentNavigation(e, rangeField.ids.field.field.get());
 		}
 	}
 
diff --git a/src/lib/builders/dialog/create.ts b/src/lib/builders/dialog/create.ts
index 9fc989b4..932d74ad 100644
--- a/src/lib/builders/dialog/create.ts
+++ b/src/lib/builders/dialog/create.ts
@@ -18,16 +18,17 @@ import {
 	kbd,
 	last,
 	noop,
+	omit,
 	overridable,
 	removeScroll,
 	sleep,
 	styleToString,
 	toWritableStores,
-	omit,
 } from '$lib/internal/helpers/index.js';
+import { withGet } from '$lib/internal/helpers/withGet.js';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
 import { tick } from 'svelte';
-import { derived, get, writable } from 'svelte/store';
+import { derived, writable } from 'svelte/store';
 import type { DialogEvents } from './events.js';
 import type { CreateDialogProps } from './types.js';
 
@@ -54,7 +55,7 @@ const defaults = {
 	onOutsideClick: undefined,
 } satisfies Defaults<CreateDialogProps>;
 
-const openDialogIds = writable<string[]>([]);
+const openDialogIds = withGet.writable<string[]>([]);
 
 export const dialogIdParts = ['content', 'title', 'description'] as const;
 export type DialogIdParts = typeof dialogIdParts;
@@ -76,7 +77,7 @@ export function createDialog(props?: CreateDialogProps) {
 		onOutsideClick,
 	} = options;
 
-	const activeTrigger = writable<HTMLElement | null>(null);
+	const activeTrigger = withGet.writable<HTMLElement | null>(null);
 
 	const ids = toWritableStores({
 		...generateIds(dialogIdParts),
@@ -102,8 +103,8 @@ export function createDialog(props?: CreateDialogProps) {
 	function handleClose() {
 		open.set(false);
 		handleFocus({
-			prop: get(closeFocus),
-			defaultEl: get(activeTrigger),
+			prop: closeFocus.get(),
+			defaultEl: activeTrigger.get(),
 		});
 	}
 
@@ -112,11 +113,11 @@ export function createDialog(props?: CreateDialogProps) {
 		sleep(100).then(() => {
 			if ($open) {
 				openDialogIds.update((prev) => {
-					prev.push(get(ids.content));
+					prev.push(ids.content.get());
 					return prev;
 				});
 			} else {
-				openDialogIds.update((prev) => prev.filter((id) => id !== get(ids.content)));
+				openDialogIds.update((prev) => prev.filter((id) => id !== ids.content.get()));
 			}
 		});
 	});
@@ -164,7 +165,7 @@ export function createDialog(props?: CreateDialogProps) {
 		action: (node: HTMLElement) => {
 			let unsubEscapeKeydown = noop;
 
-			if (get(closeOnEscape)) {
+			if (closeOnEscape.get()) {
 				const escapeKeydown = useEscapeKeydown(node, {
 					handler: () => {
 						handleClose();
@@ -188,7 +189,7 @@ export function createDialog(props?: CreateDialogProps) {
 		returned: ([$isVisible, $contentId, $descriptionId, $titleId]) => {
 			return {
 				id: $contentId,
-				role: get(role),
+				role: role.get(),
 				'aria-describedby': $descriptionId,
 				'aria-labelledby': $titleId,
 				'aria-modal': $isVisible ? ('true' as const) : undefined,
@@ -231,11 +232,11 @@ export function createDialog(props?: CreateDialogProps) {
 					return useClickOutside(node, {
 						enabled: $open,
 						handler: (e: PointerEvent) => {
-							get(onOutsideClick)?.(e);
+							onOutsideClick.get()?.(e);
 							if (e.defaultPrevented) return;
 
-							const $openDialogIds = get(openDialogIds);
-							const isLast = last($openDialogIds) === get(ids.content);
+							const $openDialogIds = openDialogIds.get();
+							const isLast = last($openDialogIds) === ids.content.get();
 							if ($closeOnOutsideClick && isLast) {
 								handleClose();
 							}
@@ -345,14 +346,14 @@ export function createDialog(props?: CreateDialogProps) {
 		if ($preventScroll && $open) unsubScroll = removeScroll();
 
 		if ($open) {
-			const contentEl = document.getElementById(get(ids.content));
-			handleFocus({ prop: get(openFocus), defaultEl: contentEl });
+			const contentEl = document.getElementById(ids.content.get());
+			handleFocus({ prop: openFocus.get(), defaultEl: contentEl });
 		}
 
 		return () => {
 			// we only want to remove the scroll lock if the dialog is not forced visible
 			// otherwise the scroll removal is handled in the `destroy` of the `content` builder
-			if (!get(forceVisible)) {
+			if (!forceVisible.get()) {
 				unsubScroll();
 			}
 		};
diff --git a/src/lib/builders/dropdown-menu/create.ts b/src/lib/builders/dropdown-menu/create.ts
index 8ba8fddf..84ff77f9 100644
--- a/src/lib/builders/dropdown-menu/create.ts
+++ b/src/lib/builders/dropdown-menu/create.ts
@@ -3,6 +3,7 @@ import { writable } from 'svelte/store';
 import { createMenuBuilder } from '../menu/index.js';
 import type { CreateDropdownMenuProps } from './types.js';
 import { omit } from '../../internal/helpers/object';
+import { withGet } from '$lib/internal/helpers/withGet.js';
 
 const defaults = {
 	arrowSize: 8,
@@ -32,9 +33,9 @@ export function createDropdownMenu(props?: CreateDropdownMenuProps) {
 	const openWritable = withDefaults.open ?? writable(withDefaults.defaultOpen);
 	const rootOpen = overridable(openWritable, withDefaults?.onOpenChange);
 
-	const rootActiveTrigger = writable<HTMLElement | null>(null);
-	const nextFocusable = writable<HTMLElement | null>(null);
-	const prevFocusable = writable<HTMLElement | null>(null);
+	const rootActiveTrigger = withGet(writable<HTMLElement | null>(null));
+	const nextFocusable = withGet(writable<HTMLElement | null>(null));
+	const prevFocusable = withGet(writable<HTMLElement | null>(null));
 
 	const {
 		trigger,
@@ -51,9 +52,9 @@ export function createDropdownMenu(props?: CreateDropdownMenuProps) {
 	} = createMenuBuilder({
 		rootOptions,
 		rootOpen,
-		rootActiveTrigger,
-		nextFocusable,
-		prevFocusable,
+		rootActiveTrigger: withGet(rootActiveTrigger),
+		nextFocusable: withGet(nextFocusable),
+		prevFocusable: withGet(prevFocusable),
 		selector: 'dropdown-menu',
 		removeScroll: true,
 		ids: withDefaults.ids,
diff --git a/src/lib/builders/link-preview/create.ts b/src/lib/builders/link-preview/create.ts
index 7152609b..d3a533a1 100644
--- a/src/lib/builders/link-preview/create.ts
+++ b/src/lib/builders/link-preview/create.ts
@@ -20,8 +20,9 @@ import {
 	toWritableStores,
 } from '$lib/internal/helpers/index.js';
 import { safeOnMount } from '$lib/internal/helpers/lifecycle';
+import { withGet, type WithGet } from '$lib/internal/helpers/withGet';
 import type { MeltActionReturn } from '$lib/internal/types.js';
-import { derived, get, writable, type Readable } from 'svelte/store';
+import { writable, type Readable } from 'svelte/store';
 import { generateIds } from '../../internal/helpers/id';
 import { omit } from '../../internal/helpers/object';
 import type { LinkPreviewEvents } from './events.js';
@@ -53,8 +54,8 @@ export function createLinkPreview(props: CreateLinkPreviewProps = {}) {
 
 	const openWritable = withDefaults.open ?? writable(withDefaults.defaultOpen);
 	const open = overridable(openWritable, withDefaults?.onOpenChange);
-	const hasSelection = writable(false);
-	const isPointerDownOnContent = writable(false);
+	const hasSelection = withGet.writable(false);
+	const isPointerDownOnContent = withGet.writable(false);
 	const containSelection = writable(false);
 	const activeTrigger = writable<HTMLElement | null>(null);
 
@@ -79,7 +80,7 @@ export function createLinkPreview(props: CreateLinkPreviewProps = {}) {
 	let timeout: number | null = null;
 	let originalBodyUserSelect: string;
 
-	const handleOpen = derived(openDelay, ($openDelay) => {
+	const handleOpen = withGet.derived(openDelay, ($openDelay) => {
 		return () => {
 			if (timeout) {
 				window.clearTimeout(timeout);
@@ -90,9 +91,9 @@ export function createLinkPreview(props: CreateLinkPreviewProps = {}) {
 				open.set(true);
 			}, $openDelay);
 		};
-	}) as Readable<() => void>;
+	}) as WithGet<Readable<() => void>>;
 
-	const handleClose = derived(
+	const handleClose = withGet.derived(
 		[closeDelay, isPointerDownOnContent, hasSelection],
 		([$closeDelay, $isPointerDownOnContent, $hasSelection]) => {
 			return () => {
@@ -107,7 +108,7 @@ export function createLinkPreview(props: CreateLinkPreviewProps = {}) {
 				}
 			};
 		}
-	) as Readable<() => void>;
+	) as WithGet<Readable<() => void>>;
 
 	const trigger = builder(name('trigger'), {
 		stores: [open, ids.trigger, ids.content],
@@ -125,17 +126,17 @@ export function createLinkPreview(props: CreateLinkPreviewProps = {}) {
 			const unsub = executeCallbacks(
 				addMeltEventListener(node, 'pointerenter', (e) => {
 					if (isTouch(e)) return;
-					get(handleOpen)();
+					handleOpen.get()();
 				}),
 				addMeltEventListener(node, 'pointerleave', (e) => {
 					if (isTouch(e)) return;
-					get(handleClose)();
+					handleClose.get()();
 				}),
 				addMeltEventListener(node, 'focus', (e) => {
 					if (!isElement(e.currentTarget) || !isFocusVisible(e.currentTarget)) return;
-					get(handleOpen)();
+					handleOpen.get()();
 				}),
-				addMeltEventListener(node, 'blur', () => get(handleClose)())
+				addMeltEventListener(node, 'blur', () => handleClose.get()())
 			);
 
 			return {
@@ -195,7 +196,7 @@ export function createLinkPreview(props: CreateLinkPreviewProps = {}) {
 							clickOutside: $closeOnOutsideClick
 								? {
 										handler: (e) => {
-											get(onOutsideClick)?.(e);
+											onOutsideClick.get()?.(e);
 											if (e.defaultPrevented) return;
 
 											if (
@@ -235,11 +236,11 @@ export function createLinkPreview(props: CreateLinkPreviewProps = {}) {
 				}),
 				addMeltEventListener(node, 'pointerenter', (e) => {
 					if (isTouch(e)) return;
-					get(handleOpen)();
+					handleOpen.get()();
 				}),
 				addMeltEventListener(node, 'pointerleave', (e) => {
 					if (isTouch(e)) return;
-					get(handleClose)();
+					handleClose.get()();
 				}),
 				addMeltEventListener(node, 'focusout', (e) => {
 					e.preventDefault();
@@ -272,7 +273,7 @@ export function createLinkPreview(props: CreateLinkPreviewProps = {}) {
 	effect([containSelection], ([$containSelection]) => {
 		if (!isBrowser || !$containSelection) return;
 		const body = document.body;
-		const contentElement = document.getElementById(get(ids.content));
+		const contentElement = document.getElementById(ids.content.get());
 		if (!contentElement) return;
 		// prefix for safari
 		originalBodyUserSelect = body.style.userSelect || body.style.webkitUserSelect;
@@ -292,7 +293,7 @@ export function createLinkPreview(props: CreateLinkPreviewProps = {}) {
 	});
 
 	safeOnMount(() => {
-		const triggerEl = document.getElementById(get(ids.trigger));
+		const triggerEl = document.getElementById(ids.trigger.get());
 		if (!triggerEl) return;
 		activeTrigger.set(triggerEl);
 	});
@@ -317,7 +318,7 @@ export function createLinkPreview(props: CreateLinkPreviewProps = {}) {
 
 		document.addEventListener('pointerup', handlePointerUp);
 
-		const contentElement = document.getElementById(get(ids.content));
+		const contentElement = document.getElementById(ids.content.get());
 		if (!contentElement) return;
 		const tabbables = getTabbableNodes(contentElement);
 		tabbables.forEach((tabbable) => tabbable.setAttribute('tabindex', '-1'));
diff --git a/src/lib/builders/listbox/create.ts b/src/lib/builders/listbox/create.ts
index 90ebbd01..9d736bf5 100644
--- a/src/lib/builders/listbox/create.ts
+++ b/src/lib/builders/listbox/create.ts
@@ -37,6 +37,7 @@ import {
 	styleToString,
 	toWritableStores,
 	toggle,
+	withGet,
 } from '$lib/internal/helpers/index.js';
 import { safeOnMount } from '$lib/internal/helpers/lifecycle';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
@@ -106,9 +107,9 @@ export function createListbox<
 	const withDefaults = { ...defaults, ...props } satisfies CreateListboxProps<Value, Multiple, S>;
 
 	// Trigger element for the popper portal. This will be our input element.
-	const activeTrigger = writable<HTMLElement | null>(null);
+	const activeTrigger = withGet(writable<HTMLElement | null>(null));
 	// The currently highlighted menu item.
-	const highlightedItem = writable<HTMLElement | null>(null);
+	const highlightedItem = withGet(writable<HTMLElement | null>(null));
 
 	const selectedWritable =
 		withDefaults.selected ?? writable<S | undefined>(withDefaults.defaultSelected);
@@ -154,10 +155,10 @@ export function createListbox<
 	const { handleTypeaheadSearch } = createTypeaheadSearch({
 		onMatch: (element) => {
 			highlightedItem.set(element);
-			element.scrollIntoView({ block: get(scrollAlignment) });
+			element.scrollIntoView({ block: scrollAlignment.get() });
 		},
 		getCurrentItem() {
-			return get(highlightedItem);
+			return highlightedItem.get();
 		},
 	});
 
@@ -178,7 +179,7 @@ export function createListbox<
 
 	const setOption = (newOption: ListboxOption<Value>) => {
 		selected.update(($option) => {
-			const $multiple = get(multiple);
+			const $multiple = multiple.get();
 			if ($multiple) {
 				const optionArr = Array.isArray($option) ? $option : [];
 				return toggle(newOption, optionArr, (itemA, itemB) =>
@@ -207,7 +208,7 @@ export function createListbox<
 	async function openMenu() {
 		open.set(true);
 
-		const triggerEl = document.getElementById(get(ids.trigger));
+		const triggerEl = document.getElementById(ids.trigger.get());
 		if (!triggerEl) return;
 
 		// The active trigger is used to anchor the menu to the input element.
@@ -216,7 +217,7 @@ export function createListbox<
 		// Wait a tick for the menu to open then highlight the selected item.
 		await tick();
 
-		const menuElement = document.getElementById(get(ids.menu));
+		const menuElement = document.getElementById(ids.menu.get());
 		if (!isHTMLElement(menuElement)) return;
 
 		const selectedItem = menuElement.querySelector('[aria-selected=true]');
@@ -294,7 +295,7 @@ export function createListbox<
 			const unsubscribe = executeCallbacks(
 				addMeltEventListener(node, 'click', () => {
 					node.focus(); // Fix for safari not adding focus on trigger
-					const $open = get(open);
+					const $open = open.get();
 					if ($open) {
 						closeMenu();
 					} else {
@@ -303,7 +304,7 @@ export function createListbox<
 				}),
 				// Handle all input key events including typing, meta, and navigation.
 				addMeltEventListener(node, 'keydown', (e) => {
-					const $open = get(open);
+					const $open = open.get();
 					/**
 					 * When the menu is closed...
 					 */
@@ -333,10 +334,10 @@ export function createListbox<
 						openMenu();
 
 						tick().then(() => {
-							const $selectedItem = get(selected);
+							const $selectedItem = selected.get();
 							if ($selectedItem) return;
 
-							const menuEl = document.getElementById(get(ids.menu));
+							const menuEl = document.getElementById(ids.menu.get());
 							if (!isHTMLElement(menuEl)) return;
 
 							const enabledItems = Array.from(
@@ -349,10 +350,10 @@ export function createListbox<
 
 							if (e.key === kbd.ARROW_DOWN) {
 								highlightedItem.set(enabledItems[0]);
-								enabledItems[0].scrollIntoView({ block: get(scrollAlignment) });
+								enabledItems[0].scrollIntoView({ block: scrollAlignment.get() });
 							} else if (e.key === kbd.ARROW_UP) {
 								highlightedItem.set(last(enabledItems));
-								last(enabledItems).scrollIntoView({ block: get(scrollAlignment) });
+								last(enabledItems).scrollIntoView({ block: scrollAlignment.get() });
 							}
 						});
 					}
@@ -367,11 +368,11 @@ export function createListbox<
 					// Pressing enter with a highlighted item should select it.
 					if (e.key === kbd.ENTER || (e.key === kbd.SPACE && isHTMLButtonElement(node))) {
 						e.preventDefault();
-						const $highlightedItem = get(highlightedItem);
+						const $highlightedItem = highlightedItem.get();
 						if ($highlightedItem) {
 							selectItem($highlightedItem);
 						}
-						if (!get(multiple)) {
+						if (!multiple.get()) {
 							closeMenu();
 						}
 					}
@@ -384,7 +385,7 @@ export function createListbox<
 					if (FIRST_LAST_KEYS.includes(e.key)) {
 						e.preventDefault();
 						// Get all the menu items.
-						const menuElement = document.getElementById(get(ids.menu));
+						const menuElement = document.getElementById(ids.menu.get());
 						if (!isHTMLElement(menuElement)) return;
 						const itemElements = getOptions(menuElement);
 						if (!itemElements.length) return;
@@ -393,11 +394,11 @@ export function createListbox<
 							(opt) => !isElementDisabled(opt) && opt.dataset.hidden === undefined
 						);
 						// Get the index of the currently highlighted item.
-						const $currentItem = get(highlightedItem);
+						const $currentItem = highlightedItem.get();
 						const currentIndex = $currentItem ? candidateNodes.indexOf($currentItem) : -1;
 						// Find the next menu item to highlight.
-						const $loop = get(loop);
-						const $scrollAlignment = get(scrollAlignment);
+						const $loop = loop.get();
+						const $scrollAlignment = scrollAlignment.get();
 						let nextItem: HTMLElement;
 						switch (e.key) {
 							case kbd.ARROW_DOWN:
@@ -424,8 +425,8 @@ export function createListbox<
 						// Highlight the new item and scroll it into view.
 						highlightedItem.set(nextItem);
 						nextItem?.scrollIntoView({ block: $scrollAlignment });
-					} else if (get(typeahead)) {
-						const menuEl = document.getElementById(get(ids.menu));
+					} else if (typeahead.get()) {
+						const menuEl = document.getElementById(ids.menu.get());
 						if (!isHTMLElement(menuEl)) return;
 
 						handleTypeaheadSearch(e.key, getOptions(menuEl));
@@ -478,7 +479,7 @@ export function createListbox<
 
 						if (!$isVisible || !$activeTrigger) return;
 
-						const ignoreHandler = createClickOutsideIgnore(get(ids.trigger));
+						const ignoreHandler = createClickOutsideIgnore(ids.trigger.get());
 
 						const popper = usePopper(node, {
 							anchorElement: $activeTrigger,
@@ -489,7 +490,7 @@ export function createListbox<
 								clickOutside: $closeOnOutsideClick
 									? {
 											handler: (e) => {
-												get(onOutsideClick)?.(e);
+												onOutsideClick.get()?.(e);
 												if (e.defaultPrevented) return;
 
 												const target = e.target;
@@ -566,7 +567,7 @@ export function createListbox<
 					}
 					// Otherwise, select the item and close the menu.
 					selectItem(node);
-					if (!get(multiple)) {
+					if (!multiple.get()) {
 						closeMenu();
 					}
 				}),
@@ -637,10 +638,10 @@ export function createListbox<
 
 	safeOnMount(() => {
 		if (!isBrowser) return;
-		const menuEl = document.getElementById(get(ids.menu));
+		const menuEl = document.getElementById(ids.menu.get());
 		if (!menuEl) return;
 
-		const triggerEl = document.getElementById(get(ids.trigger));
+		const triggerEl = document.getElementById(ids.trigger.get());
 		if (triggerEl) {
 			activeTrigger.set(triggerEl);
 		}
@@ -655,7 +656,7 @@ export function createListbox<
 	 */
 	effect([highlightedItem], ([$highlightedItem]) => {
 		if (!isBrowser) return;
-		const menuElement = document.getElementById(get(ids.menu));
+		const menuElement = document.getElementById(ids.menu.get());
 		if (!isHTMLElement(menuElement)) return;
 		getOptions(menuElement).forEach((node) => {
 			if (node === $highlightedItem) {
@@ -671,7 +672,7 @@ export function createListbox<
 
 		let unsubScroll = noop;
 
-		if (get(preventScroll) && $open) {
+		if (preventScroll.get() && $open) {
 			unsubScroll = removeScroll();
 		}
 
diff --git a/src/lib/builders/menu/create.ts b/src/lib/builders/menu/create.ts
index 1fb3b168..52754ec5 100644
--- a/src/lib/builders/menu/create.ts
+++ b/src/lib/builders/menu/create.ts
@@ -10,7 +10,6 @@ import {
 	createElHelpers,
 	createTypeaheadSearch,
 	derivedVisible,
-	derivedWithUnsubscribe,
 	disabledAttr,
 	effect,
 	executeCallbacks,
@@ -35,9 +34,10 @@ import {
 } from '$lib/internal/helpers/index.js';
 import type { Defaults, MeltActionReturn, TextDirection } from '$lib/internal/types.js';
 import { tick } from 'svelte';
-import { derived, get, writable, type Writable } from 'svelte/store';
+import { derived, writable, type Writable } from 'svelte/store';
 
 import { safeOnMount } from '$lib/internal/helpers/lifecycle.js';
+import { withGet, type WithGet } from '$lib/internal/helpers/withGet.js';
 import type { MenuEvents } from './events.js';
 import type {
 	Selector,
@@ -116,31 +116,30 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 	 * This is used to determine how we handle focus on open behavior differently
 	 * than when the user is using the mouse.
 	 */
-	const isUsingKeyboard = writable(false);
+	const isUsingKeyboard = withGet.writable(false);
 
 	/**
 	 * Stores used to manage the grace area for submenus. This prevents us
 	 * from closing a submenu when the user is moving their mouse from the
 	 * trigger to the submenu.
 	 */
-	const lastPointerX = writable(0);
-	const pointerGraceIntent = writable<GraceIntent | null>(null);
-	const pointerDir = writable<Side>('right');
+	const lastPointerX = withGet(writable(0));
+	const pointerGraceIntent = withGet(writable<GraceIntent | null>(null));
+	const pointerDir = withGet(writable<Side>('right'));
 
 	/**
 	 * Track currently focused item in the menu.
 	 */
-	const currentFocusedItem = writable<HTMLElement | null>(null);
+	const currentFocusedItem = withGet(writable<HTMLElement | null>(null));
 
-	const pointerMovingToSubmenu = derivedWithUnsubscribe(
-		[pointerDir, pointerGraceIntent],
-		([$pointerDir, $pointerGraceIntent]) => {
+	const pointerMovingToSubmenu = withGet(
+		derived([pointerDir, pointerGraceIntent], ([$pointerDir, $pointerGraceIntent]) => {
 			return (e: PointerEvent) => {
 				const isMovingTowards = $pointerDir === $pointerGraceIntent?.side;
 
 				return isMovingTowards && isPointerInGraceArea(e, $pointerGraceIntent?.area);
 			};
-		}
+		})
 	);
 
 	const { typed, handleTypeaheadSearch } = createTypeaheadSearch();
@@ -194,7 +193,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 								clickOutside: $closeOnOutsideClick
 									? {
 											handler: (e) => {
-												get(onOutsideClick)?.(e);
+												onOutsideClick.get()?.(e);
 												if (e.defaultPrevented) return;
 
 												if (
@@ -233,7 +232,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 
 					if (!isKeyDownInside) return;
 					if (FIRST_LAST_KEYS.includes(e.key)) {
-						handleMenuNavigation(e, get(loop) ?? false);
+						handleMenuNavigation(e, loop.get() ?? false);
 					}
 
 					/**
@@ -252,7 +251,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 					 */
 					const isCharacterKey = e.key.length === 1;
 					const isModifierKey = e.ctrlKey || e.altKey || e.metaKey;
-					if (!isModifierKey && isCharacterKey && get(typeahead) === true) {
+					if (!isModifierKey && isCharacterKey && typeahead.get() === true) {
 						handleTypeaheadSearch(e.key, getMenuItems(menuEl));
 					}
 				})
@@ -287,7 +286,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 
 			const unsub = executeCallbacks(
 				addMeltEventListener(node, 'click', (e) => {
-					const $rootOpen = get(rootOpen);
+					const $rootOpen = rootOpen.get();
 					const triggerEl = e.currentTarget;
 					if (!isHTMLElement(triggerEl)) return;
 
@@ -366,7 +365,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 						return;
 					}
 
-					if (get(closeOnItemClick)) {
+					if (closeOnItemClick.get()) {
 						// Allows forms to submit before the menu is removed from the DOM
 						sleep(1).then(() => {
 							rootOpen.set(false);
@@ -466,7 +465,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 							return !prev;
 						});
 
-						if (get(closeOnItemClick)) {
+						if (closeOnItemClick.get()) {
 							// We're waiting for a tick to let the checked store update
 							// before closing the menu. If we don't, and the user was to hit
 							// spacebar or enter twice really fast, the menu would close and
@@ -594,7 +593,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 
 						value.set(itemValue);
 
-						if (get(closeOnItemClick)) {
+						if (closeOnItemClick.get()) {
 							// We're waiting for a tick to let the checked store update
 							// before closing the menu. If we don't, and the user was to hit
 							// spacebar or enter twice really fast, the menu would close and
@@ -686,9 +685,9 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 
 		const { positioning, arrowSize, disabled } = options;
 
-		const subActiveTrigger = writable<HTMLElement | null>(null);
-		const subOpenTimer = writable<number | null>(null);
-		const pointerGraceTimer = writable(0);
+		const subActiveTrigger = withGet(writable<HTMLElement | null>(null));
+		const subOpenTimer = withGet(writable<number | null>(null));
+		const pointerGraceTimer = withGet(writable(0));
 
 		const subIds = toWritableStores({ ...generateIds(menuIdParts), ...withDefaults.ids });
 
@@ -697,7 +696,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 			 * Set active trigger on mount to handle controlled/forceVisible
 			 * state.
 			 */
-			const subTrigger = document.getElementById(get(subIds.trigger));
+			const subTrigger = document.getElementById(subIds.trigger.get());
 			if (subTrigger) {
 				subActiveTrigger.set(subTrigger);
 			}
@@ -735,7 +734,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 					([$subIsVisible, $positioning]) => {
 						unsubPopper();
 						if (!$subIsVisible) return;
-						const activeTrigger = get(subActiveTrigger);
+						const activeTrigger = subActiveTrigger.get();
 						if (!activeTrigger) return;
 						tick().then(() => {
 							const parentMenuEl = getParentMenu(activeTrigger);
@@ -777,7 +776,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 						if (FIRST_LAST_KEYS.includes(e.key)) {
 							// prevent events from bubbling
 							e.stopImmediatePropagation();
-							handleMenuNavigation(e, get(loop) ?? false);
+							handleMenuNavigation(e, loop.get() ?? false);
 							return;
 						}
 
@@ -787,7 +786,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 
 						// close the submenu if the user presses a close key
 						if (isCloseKey) {
-							const $subActiveTrigger = get(subActiveTrigger);
+							const $subActiveTrigger = subActiveTrigger.get();
 							e.preventDefault();
 							subOpen.update(() => {
 								if ($subActiveTrigger) {
@@ -809,7 +808,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 							return;
 						}
 
-						if (!isModifierKey && isCharacterKey && get(typeahead) === true) {
+						if (!isModifierKey && isCharacterKey && typeahead.get() === true) {
 							// typeahead logic
 							handleTypeaheadSearch(e.key, getMenuItems(menuEl));
 						}
@@ -818,10 +817,10 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 						onMenuPointerMove(e);
 					}),
 					addMeltEventListener(node, 'focusout', (e) => {
-						const $subActiveTrigger = get(subActiveTrigger);
-						if (get(isUsingKeyboard)) {
+						const $subActiveTrigger = subActiveTrigger.get();
+						if (isUsingKeyboard.get()) {
 							const target = e.target;
-							const submenuEl = document.getElementById(get(subIds.menu));
+							const submenuEl = document.getElementById(subIds.menu.get());
 							if (!isHTMLElement(submenuEl) || !isHTMLElement(target)) return;
 
 							if (!submenuEl.contains(target) && target !== $subActiveTrigger) {
@@ -873,7 +872,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 
 				const unsubTimer = () => {
 					clearTimerStore(subOpenTimer);
-					window.clearTimeout(get(pointerGraceTimer));
+					window.clearTimeout(pointerGraceTimer.get());
 					pointerGraceIntent.set(null);
 				};
 
@@ -886,7 +885,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 
 						// Manually focus because iOS Safari doesn't always focus on click (e.g. buttons)
 						handleRovingFocus(triggerEl);
-						if (!get(subOpen)) {
+						if (!subOpen.get()) {
 							subOpen.update((prev) => {
 								const isAlreadyOpen = prev;
 								if (!isAlreadyOpen) {
@@ -898,14 +897,14 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 						}
 					}),
 					addMeltEventListener(node, 'keydown', (e) => {
-						const $typed = get(typed);
+						const $typed = typed.get();
 						const triggerEl = e.currentTarget;
 						if (!isHTMLElement(triggerEl) || isElementDisabled(triggerEl)) return;
 						const isTypingAhead = $typed.length > 0;
 						if (isTypingAhead && e.key === kbd.SPACE) return;
 
 						if (SUB_OPEN_KEYS['ltr'].includes(e.key)) {
-							if (!get(subOpen)) {
+							if (!subOpen.get()) {
 								triggerEl.click();
 								e.preventDefault();
 								return;
@@ -929,12 +928,12 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 
 						const triggerEl = e.currentTarget;
 						if (!isHTMLElement(triggerEl)) return;
-						if (!isFocusWithinSubmenu(get(subIds.menu))) {
+						if (!isFocusWithinSubmenu(subIds.menu.get())) {
 							handleRovingFocus(triggerEl);
 						}
 
-						const openTimer = get(subOpenTimer);
-						if (!get(subOpen) && !openTimer && !isElementDisabled(triggerEl)) {
+						const openTimer = subOpenTimer.get();
+						if (!subOpen.get() && !openTimer && !isElementDisabled(triggerEl)) {
 							subOpenTimer.set(
 								window.setTimeout(() => {
 									subOpen.update(() => {
@@ -950,7 +949,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 						if (!isMouse(e)) return;
 						clearTimerStore(subOpenTimer);
 
-						const submenuEl = document.getElementById(get(subIds.menu));
+						const submenuEl = document.getElementById(subIds.menu.get());
 						const contentRect = submenuEl?.getBoundingClientRect();
 
 						if (contentRect) {
@@ -973,7 +972,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 								side,
 							});
 
-							window.clearTimeout(get(pointerGraceTimer));
+							window.clearTimeout(pointerGraceTimer.get());
 							pointerGraceTimer.set(
 								window.setTimeout(() => {
 									pointerGraceIntent.set(null);
@@ -1044,17 +1043,17 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 
 		effect([pointerGraceIntent], ([$pointerGraceIntent]) => {
 			if (!isBrowser || $pointerGraceIntent) return;
-			window.clearTimeout(get(pointerGraceTimer));
+			window.clearTimeout(pointerGraceTimer.get());
 		});
 
 		effect([subOpen], ([$subOpen]) => {
 			if (!isBrowser) return;
 
 			sleep(1).then(() => {
-				const menuEl = document.getElementById(get(subIds.menu));
+				const menuEl = document.getElementById(subIds.menu.get());
 				if (!menuEl) return;
 
-				if ($subOpen && get(isUsingKeyboard)) {
+				if ($subOpen && isUsingKeyboard.get()) {
 					// Selector to get menu items belonging to menu
 					const menuItems = getMenuItems(menuEl);
 					if (!menuItems.length) return;
@@ -1062,13 +1061,13 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 				}
 
 				if (!$subOpen) {
-					const focusedItem = get(currentFocusedItem);
+					const focusedItem = currentFocusedItem.get();
 					if (focusedItem && menuEl.contains(focusedItem)) {
 						removeHighlight(focusedItem);
 					}
 				}
 				if (menuEl && !$subOpen) {
-					const subTriggerEl = document.getElementById(get(subIds.trigger));
+					const subTriggerEl = document.getElementById(subIds.trigger.get());
 					if (!subTriggerEl || document.activeElement === subTriggerEl) return;
 					removeHighlight(subTriggerEl);
 				}
@@ -1095,8 +1094,8 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 		 * case where the user sets the `open` store to `true` without
 		 * clicking on the trigger.
 		 */
-		const triggerEl = document.getElementById(get(rootIds.trigger));
-		if (isHTMLElement(triggerEl) && get(rootOpen)) {
+		const triggerEl = document.getElementById(rootIds.trigger.get());
+		if (isHTMLElement(triggerEl) && rootOpen.get()) {
 			rootActiveTrigger.set(triggerEl);
 		}
 
@@ -1115,7 +1114,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 		};
 
 		const keydownListener = (e: KeyboardEvent) => {
-			if (e.key === kbd.ESCAPE && get(closeOnEscape)) {
+			if (e.key === kbd.ESCAPE && closeOnEscape.get()) {
 				rootOpen.set(false);
 				return;
 			}
@@ -1141,9 +1140,9 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 	effect([rootOpen], ([$rootOpen]) => {
 		if (!isBrowser) return;
 		if (!$rootOpen) {
-			const $rootActiveTrigger = get(rootActiveTrigger);
+			const $rootActiveTrigger = rootActiveTrigger.get();
 			if (!$rootActiveTrigger) return;
-			const $closeFocus = get(closeFocus);
+			const $closeFocus = closeFocus.get();
 
 			if (!$rootOpen && $rootActiveTrigger) {
 				handleFocus({ prop: $closeFocus, defaultEl: $rootActiveTrigger });
@@ -1163,9 +1162,9 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 		// if the menu is open, we'll sleep for a sec so the menu can render
 		// before we focus on either the first item or the menu itself.
 		sleep(1).then(() => {
-			const menuEl = document.getElementById(get(rootIds.menu));
-			if (menuEl && $rootOpen && get(isUsingKeyboard)) {
-				if (get(disableFocusFirstItem)) {
+			const menuEl = document.getElementById(rootIds.menu.get());
+			if (menuEl && $rootOpen && isUsingKeyboard.get()) {
+				if (disableFocusFirstItem.get()) {
 					handleRovingFocus(menuEl);
 					return;
 				}
@@ -1189,7 +1188,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 		const handlePointer = () => isUsingKeyboard.set(false);
 		const handleKeyDown = (e: KeyboardEvent) => {
 			isUsingKeyboard.set(true);
-			if (e.key === kbd.ESCAPE && $rootOpen && get(closeOnEscape)) {
+			if (e.key === kbd.ESCAPE && $rootOpen && closeOnEscape.get()) {
 				rootOpen.set(false);
 				return;
 			}
@@ -1222,7 +1221,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 	function onItemFocusIn(e: FocusEvent) {
 		const itemEl = e.currentTarget;
 		if (!isHTMLElement(itemEl)) return;
-		const $currentFocusedItem = get(currentFocusedItem);
+		const $currentFocusedItem = currentFocusedItem.get();
 		if ($currentFocusedItem) {
 			removeHighlight($currentFocusedItem);
 		}
@@ -1278,7 +1277,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 		const currentTarget = e.currentTarget;
 		if (!isHTMLElement(currentTarget) || !isHTMLElement(target)) return;
 
-		const $lastPointerX = get(lastPointerX);
+		const $lastPointerX = lastPointerX.get();
 		const pointerXHasChanged = $lastPointerX !== e.clientX;
 
 		// We don't use `e.movementX` for this check because Safari will
@@ -1318,7 +1317,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 	 * -----------------------------------------------------------------------------------------------*/
 
 	function onItemKeyDown(e: KeyboardEvent) {
-		const $typed = get(typed);
+		const $typed = typed.get();
 		const isTypingAhead = $typed.length > 0;
 		if (isTypingAhead && e.key === kbd.SPACE) {
 			e.preventDefault();
@@ -1348,7 +1347,7 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 	}
 
 	function isPointerMovingToSubmenu(e: PointerEvent) {
-		return get(pointerMovingToSubmenu)(e);
+		return pointerMovingToSubmenu.get()(e);
 	}
 
 	/**
@@ -1381,18 +1380,18 @@ export function createMenuBuilder(opts: _MenuBuilderOptions) {
 
 export function handleTabNavigation(
 	e: KeyboardEvent,
-	nextFocusable: Writable<HTMLElement | null>,
-	prevFocusable: Writable<HTMLElement | null>
+	nextFocusable: WithGet<Writable<HTMLElement | null>>,
+	prevFocusable: WithGet<Writable<HTMLElement | null>>
 ) {
 	if (e.shiftKey) {
-		const $prevFocusable = get(prevFocusable);
+		const $prevFocusable = prevFocusable.get();
 		if ($prevFocusable) {
 			e.preventDefault();
 			sleep(1).then(() => $prevFocusable.focus());
 			prevFocusable.set(null);
 		}
 	} else {
-		const $nextFocusable = get(nextFocusable);
+		const $nextFocusable = nextFocusable.get();
 		if ($nextFocusable) {
 			e.preventDefault();
 			sleep(1).then(() => $nextFocusable.focus());
@@ -1424,9 +1423,9 @@ export function applyAttrsIfDisabled(element: HTMLElement | null) {
  * Given a timer store, clear the timeout and set the store to null
  * @param openTimer The timer store
  */
-export function clearTimerStore(timerStore: Writable<number | null>) {
+export function clearTimerStore(timerStore: WithGet<Writable<number | null>>) {
 	if (!isBrowser) return;
-	const timer = get(timerStore);
+	const timer = timerStore.get();
 	if (timer) {
 		window.clearTimeout(timer);
 		timerStore.set(null);
diff --git a/src/lib/builders/menu/types.ts b/src/lib/builders/menu/types.ts
index a5ff239f..614551bf 100644
--- a/src/lib/builders/menu/types.ts
+++ b/src/lib/builders/menu/types.ts
@@ -3,6 +3,7 @@ import type { TextDirection } from '$lib/internal/types.js';
 import type { ChangeFn, FocusProp, IdObj } from '$lib/internal/helpers/index.js';
 import type { Writable } from 'svelte/store';
 import type { _MenuIdParts, createMenuBuilder } from './create.js';
+import type { WithGet } from '$lib/internal/helpers/withGet.js';
 
 export type _CreateMenuProps = {
 	/**
@@ -173,27 +174,27 @@ export type _Menu = {
 };
 
 export type _MenuBuilderOptions = {
-	rootOpen: Writable<boolean>;
-	rootActiveTrigger: Writable<HTMLElement | null>;
+	rootOpen: WithGet<Writable<boolean>>;
+	rootActiveTrigger: WithGet<Writable<HTMLElement | null>>;
 	rootOptions: {
-		positioning: Writable<FloatingConfig>;
-		arrowSize: Writable<number | undefined>;
-		preventScroll: Writable<boolean | undefined>;
-		loop: Writable<boolean | undefined>;
-		dir: Writable<TextDirection>;
-		closeOnEscape: Writable<boolean>;
-		closeOnOutsideClick: Writable<boolean>;
-		portal: Writable<string | HTMLElement | undefined | null>;
-		forceVisible: Writable<boolean>;
-		typeahead: Writable<boolean>;
-		closeFocus: Writable<FocusProp | undefined>;
-		disableFocusFirstItem: Writable<boolean>;
-		closeOnItemClick: Writable<boolean>;
-		onOutsideClick: Writable<((event: PointerEvent) => void) | undefined>;
+		positioning: WithGet<Writable<FloatingConfig>>;
+		arrowSize: WithGet<Writable<number | undefined>>;
+		preventScroll: WithGet<Writable<boolean | undefined>>;
+		loop: WithGet<Writable<boolean | undefined>>;
+		dir: WithGet<Writable<TextDirection>>;
+		closeOnEscape: WithGet<Writable<boolean>>;
+		closeOnOutsideClick: WithGet<Writable<boolean>>;
+		portal: WithGet<Writable<string | HTMLElement | undefined | null>>;
+		forceVisible: WithGet<Writable<boolean>>;
+		typeahead: WithGet<Writable<boolean>>;
+		closeFocus: WithGet<Writable<FocusProp | undefined>>;
+		disableFocusFirstItem: WithGet<Writable<boolean>>;
+		closeOnItemClick: WithGet<Writable<boolean>>;
+		onOutsideClick: WithGet<Writable<((event: PointerEvent) => void) | undefined>>;
 	};
 
-	nextFocusable: Writable<HTMLElement | null>;
-	prevFocusable: Writable<HTMLElement | null>;
+	nextFocusable: WithGet<Writable<HTMLElement | null>>;
+	prevFocusable: WithGet<Writable<HTMLElement | null>>;
 	selector: string;
 	/**
 	 * When you want to handle the scroll removal in the specific menu builder,
diff --git a/src/lib/builders/menubar/create.ts b/src/lib/builders/menubar/create.ts
index 6da83a83..94f405bd 100644
--- a/src/lib/builders/menubar/create.ts
+++ b/src/lib/builders/menubar/create.ts
@@ -10,6 +10,7 @@ import {
 	derivedVisible,
 	effect,
 	executeCallbacks,
+	generateIds,
 	getNextFocusable,
 	getPortalDestination,
 	getPreviousFocusable,
@@ -19,17 +20,16 @@ import {
 	isHTMLElement,
 	kbd,
 	noop,
+	omit,
 	removeHighlight,
 	removeScroll,
 	styleToString,
 	toWritableStores,
-	generateIds,
-	omit,
 } from '$lib/internal/helpers/index.js';
 import { safeOnDestroy, safeOnMount } from '$lib/internal/helpers/lifecycle.js';
 import type { MeltActionReturn } from '$lib/internal/types.js';
 import { tick } from 'svelte';
-import { get, writable } from 'svelte/store';
+import { writable } from 'svelte/store';
 import {
 	applyAttrsIfDisabled,
 	createMenuBuilder,
@@ -40,6 +40,7 @@ import {
 } from '../menu/index.js';
 import type { MenubarEvents } from './events.js';
 import type { CreateMenubarMenuProps, CreateMenubarProps } from './types.js';
+import { withGet } from '$lib/internal/helpers/withGet.js';
 
 const MENUBAR_NAV_KEYS = [kbd.ARROW_LEFT, kbd.ARROW_RIGHT, kbd.HOME, kbd.END];
 
@@ -59,12 +60,12 @@ export function createMenubar(props?: CreateMenubarProps) {
 
 	const options = toWritableStores(omit(withDefaults, 'ids'));
 	const { loop, closeOnEscape, preventScroll } = options;
-	const activeMenu = writable<string>('');
+	const activeMenu = withGet(writable<string>(''));
 
-	const nextFocusable = writable<HTMLElement | null>(null);
-	const prevFocusable = writable<HTMLElement | null>(null);
-	const lastFocusedMenuTrigger = writable<HTMLElement | null>(null);
-	const closeTimer = writable(0);
+	const nextFocusable = withGet(writable<HTMLElement | null>(null));
+	const prevFocusable = withGet(writable<HTMLElement | null>(null));
+	const lastFocusedMenuTrigger = withGet(writable<HTMLElement | null>(null));
+	const closeTimer = withGet(writable(0));
 	let scrollRemoved = false;
 
 	const ids = toWritableStores({ ...generateIds(menubarIdParts), ...withDefaults.ids });
@@ -111,8 +112,8 @@ export function createMenubar(props?: CreateMenubarProps) {
 
 	const createMenu = (props?: CreateMenubarMenuProps) => {
 		const withDefaults = { ...menuDefaults, ...props } satisfies CreateMenubarMenuProps;
-		const rootOpen = writable(false);
-		const rootActiveTrigger = writable<HTMLElement | null>(null);
+		const rootOpen = withGet(writable(false));
+		const rootActiveTrigger = withGet(writable<HTMLElement | null>(null));
 
 		// options
 		const options = toWritableStores(withDefaults);
@@ -120,10 +121,10 @@ export function createMenubar(props?: CreateMenubarProps) {
 
 		const m = createMenuBuilder({
 			rootOptions: { ...options, preventScroll },
-			rootOpen,
-			rootActiveTrigger,
-			nextFocusable,
-			prevFocusable,
+			rootOpen: withGet(rootOpen),
+			rootActiveTrigger: withGet(rootActiveTrigger),
+			nextFocusable: withGet(nextFocusable),
+			prevFocusable: withGet(prevFocusable),
 			selector: 'menubar-menu',
 			removeScroll: false,
 		});
@@ -171,12 +172,12 @@ export function createMenubar(props?: CreateMenubarProps) {
 										? {
 												ignore: (e) => {
 													const target = e.target;
-													const menubarEl = document.getElementById(get(ids.menubar));
+													const menubarEl = document.getElementById(ids.menubar.get());
 													if (!menubarEl || !isElement(target)) return false;
 													return menubarEl.contains(target);
 												},
 												handler: (e) => {
-													get(onOutsideClick)?.(e);
+													onOutsideClick.get()?.(e);
 													if (e.defaultPrevented) return;
 													activeMenu.set('');
 												},
@@ -261,7 +262,7 @@ export function createMenubar(props?: CreateMenubarProps) {
 			action: (node: HTMLElement): MeltActionReturn<MenubarEvents['trigger']> => {
 				applyAttrsIfDisabled(node);
 
-				const menubarEl = document.getElementById(get(ids.menubar));
+				const menubarEl = document.getElementById(ids.menubar.get());
 				if (!menubarEl) return {};
 
 				const menubarTriggers = Array.from(
@@ -288,7 +289,7 @@ export function createMenubar(props?: CreateMenubarProps) {
 
 				const unsub = executeCallbacks(
 					addMeltEventListener(node, 'click', (e) => {
-						const $rootOpen = get(rootOpen);
+						const $rootOpen = rootOpen.get();
 						const triggerEl = e.currentTarget;
 						if (!isHTMLElement(triggerEl)) return;
 
@@ -319,11 +320,11 @@ export function createMenubar(props?: CreateMenubarProps) {
 						const triggerEl = e.currentTarget;
 						if (!isHTMLElement(triggerEl)) return;
 
-						const $activeMenu = get(activeMenu);
-						const $rootOpen = get(rootOpen);
+						const $activeMenu = activeMenu.get();
+						const $rootOpen = rootOpen.get();
 						if ($activeMenu && !$rootOpen) {
 							rootOpen.set(true);
-							activeMenu.set(get(m.ids.menu));
+							activeMenu.set(m.ids.menu.get());
 							rootActiveTrigger.set(triggerEl);
 						}
 					})
@@ -345,7 +346,7 @@ export function createMenubar(props?: CreateMenubarProps) {
 					nextFocusable.set(getNextFocusable(triggerEl));
 					prevFocusable.set(getPreviousFocusable(triggerEl));
 					rootActiveTrigger.set(triggerEl);
-					activeMenu.set(get(m.ids.menu));
+					activeMenu.set(m.ids.menu.get());
 				} else {
 					rootActiveTrigger.set(null);
 				}
@@ -356,10 +357,10 @@ export function createMenubar(props?: CreateMenubarProps) {
 
 		effect([activeMenu], ([$activeMenu]) => {
 			if (!isBrowser) return;
-			if ($activeMenu === get(m.ids.menu)) {
-				if (get(rootOpen)) return;
+			if ($activeMenu === m.ids.menu.get()) {
+				if (rootOpen.get()) return;
 
-				const triggerEl = document.getElementById(get(m.ids.trigger));
+				const triggerEl = document.getElementById(m.ids.trigger.get());
 				if (!triggerEl) return;
 				rootActiveTrigger.set(triggerEl);
 				addHighlight(triggerEl);
@@ -367,10 +368,10 @@ export function createMenubar(props?: CreateMenubarProps) {
 				return;
 			}
 
-			if ($activeMenu !== get(m.ids.menu)) {
+			if ($activeMenu !== m.ids.menu.get()) {
 				if (!isBrowser) return;
-				if (get(rootOpen)) {
-					const triggerEl = document.getElementById(get(m.ids.trigger));
+				if (rootOpen.get()) {
+					const triggerEl = document.getElementById(m.ids.trigger.get());
 					if (!triggerEl) return;
 					rootActiveTrigger.set(null);
 					rootOpen.set(false);
@@ -382,9 +383,9 @@ export function createMenubar(props?: CreateMenubarProps) {
 
 		effect([rootOpen], ([$rootOpen]) => {
 			if (!isBrowser) return;
-			const triggerEl = document.getElementById(get(m.ids.trigger));
+			const triggerEl = document.getElementById(m.ids.trigger.get());
 			if (!triggerEl) return;
-			if (!$rootOpen && get(activeMenu) === get(m.ids.menu)) {
+			if (!$rootOpen && activeMenu.get() === m.ids.menu.get()) {
 				rootActiveTrigger.set(null);
 				activeMenu.set('');
 				removeHighlight(triggerEl);
@@ -398,8 +399,8 @@ export function createMenubar(props?: CreateMenubarProps) {
 
 		safeOnMount(() => {
 			if (!isBrowser) return;
-			const triggerEl = document.getElementById(get(m.ids.trigger));
-			if (isHTMLElement(triggerEl) && get(rootOpen)) {
+			const triggerEl = document.getElementById(m.ids.trigger.get());
+			if (isHTMLElement(triggerEl) && rootOpen.get()) {
 				rootActiveTrigger.set(triggerEl);
 			}
 		});
@@ -457,7 +458,7 @@ export function createMenubar(props?: CreateMenubarProps) {
 		if (isPrevKey && isKeyDownInsideSubMenu) return;
 
 		// Index of the currently focused item in the candidate nodes array
-		const menubarEl = document.getElementById(get(ids.menubar));
+		const menubarEl = document.getElementById(ids.menubar.get());
 		if (!isHTMLElement(menubarEl)) return;
 		const triggers = getMenuTriggers(menubarEl);
 		const currTriggerId = currentTarget.getAttribute('aria-labelledby');
@@ -527,7 +528,7 @@ export function createMenubar(props?: CreateMenubarProps) {
 
 		// Calculate the index of the next menu item
 		let nextIndex: number;
-		const $loop = get(loop);
+		const $loop = loop.get();
 		switch (e.key) {
 			case kbd.ARROW_RIGHT:
 				nextIndex =
@@ -556,7 +557,7 @@ export function createMenubar(props?: CreateMenubarProps) {
 	safeOnMount(() => {
 		if (!isBrowser) return;
 
-		const menubarEl = document.getElementById(get(ids.menubar));
+		const menubarEl = document.getElementById(ids.menubar.get());
 		if (!menubarEl) return;
 		const unsubEvents = executeCallbacks(
 			addMeltEventListener(menubarEl, 'keydown', (e) => {
@@ -575,8 +576,8 @@ export function createMenubar(props?: CreateMenubarProps) {
 				}
 			}),
 			addEventListener(document, 'keydown', (e) => {
-				if (get(closeOnEscape) && e.key === kbd.ESCAPE) {
-					window.clearTimeout(get(closeTimer));
+				if (closeOnEscape.get() && e.key === kbd.ESCAPE) {
+					window.clearTimeout(closeTimer.get());
 					activeMenu.set('');
 				}
 			})
diff --git a/src/lib/builders/pagination/create.ts b/src/lib/builders/pagination/create.ts
index d3655ead..3cdf29eb 100644
--- a/src/lib/builders/pagination/create.ts
+++ b/src/lib/builders/pagination/create.ts
@@ -1,4 +1,5 @@
 import {
+	addMeltEventListener,
 	builder,
 	createElHelpers,
 	executeCallbacks,
@@ -7,13 +8,13 @@ import {
 	omit,
 	overridable,
 	toWritableStores,
-	addMeltEventListener,
 } from '$lib/internal/helpers/index.js';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
-import { derived, get, writable, readonly } from 'svelte/store';
+import { derived, readonly, writable } from 'svelte/store';
+import type { PaginationEvents } from './events.js';
 import { getPageItems } from './helpers.js';
 import type { CreatePaginationProps, Page } from './types.js';
-import type { PaginationEvents } from './events.js';
+import { withGet } from '$lib/internal/helpers/withGet.js';
 
 const defaults = {
 	perPage: 1,
@@ -34,7 +35,7 @@ export function createPagination(props: CreatePaginationProps) {
 
 	const { perPage, siblingCount, count } = options;
 
-	const totalPages = derived([count, perPage], ([$count, $perPage]) => {
+	const totalPages = withGet.derived([count, perPage], ([$count, $perPage]) => {
 		return Math.ceil($count / $perPage);
 	});
 
@@ -150,7 +151,7 @@ export function createPagination(props: CreatePaginationProps) {
 		action: (node: HTMLElement): MeltActionReturn<PaginationEvents['nextButton']> => {
 			const unsub = executeCallbacks(
 				addMeltEventListener(node, 'click', () => {
-					const $totalPages = get(totalPages);
+					const $totalPages = totalPages.get();
 					page.update((p) => Math.min(p + 1, $totalPages));
 				}),
 				addMeltEventListener(node, 'keydown', keydown)
diff --git a/src/lib/builders/pin-input/create.ts b/src/lib/builders/pin-input/create.ts
index aa12cfda..f015c396 100644
--- a/src/lib/builders/pin-input/create.ts
+++ b/src/lib/builders/pin-input/create.ts
@@ -17,10 +17,10 @@ import {
 } from '$lib/internal/helpers/index.js';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
 import { tick } from 'svelte';
-import { derived, get, readonly, writable } from 'svelte/store';
+import { derived, readonly, writable } from 'svelte/store';
+import { generateIds } from '../../internal/helpers/id';
 import type { PinInputEvents } from './events.js';
 import type { CreatePinInputProps } from './types.js';
-import { generateIds } from '../../internal/helpers/id';
 
 const { name, selector } = createElHelpers<'input' | 'hidden-input'>('pin-input');
 
@@ -75,7 +75,7 @@ export function createPinInput(props?: CreatePinInputProps) {
 
 	const getTotalItems = () => {
 		if (!isBrowser) return Infinity;
-		const rootEl = document.getElementById(get(ids.root));
+		const rootEl = document.getElementById(ids.root.get());
 		if (!rootEl) return Infinity;
 
 		const inputs = Array.from(rootEl.querySelectorAll(selector('input')));
@@ -161,7 +161,7 @@ export function createPinInput(props?: CreatePinInputProps) {
 					if (!inputs) return;
 
 					const getInputted = (el: HTMLInputElement) => {
-						const $value = get(value);
+						const $value = value.get();
 						const prevElValue = $value[elIndex];
 						const selectionStart = el.selectionStart ?? 1;
 						if (!prevElValue) return el.value;
@@ -219,7 +219,7 @@ export function createPinInput(props?: CreatePinInputProps) {
 					});
 				}),
 				addMeltEventListener(node, 'blur', () => {
-					node.placeholder = get(placeholder);
+					node.placeholder = placeholder.get();
 				})
 			);
 
diff --git a/src/lib/builders/popover/create.ts b/src/lib/builders/popover/create.ts
index 485b99af..75c7940e 100644
--- a/src/lib/builders/popover/create.ts
+++ b/src/lib/builders/popover/create.ts
@@ -23,7 +23,7 @@ import { usePopper } from '$lib/internal/actions/index.js';
 import { safeOnMount } from '$lib/internal/helpers/lifecycle.js';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
 import { tick } from 'svelte';
-import { get, writable } from 'svelte/store';
+import { writable } from 'svelte/store';
 import { generateIds } from '../../internal/helpers/id';
 import type { PopoverEvents } from './events.js';
 import type { CreatePopoverProps } from './types.js';
@@ -78,13 +78,13 @@ export function createPopover(args?: CreatePopoverProps) {
 	const ids = toWritableStores({ ...generateIds(popoverIdParts), ...withDefaults.ids });
 
 	safeOnMount(() => {
-		activeTrigger.set(document.getElementById(get(ids.trigger)));
+		activeTrigger.set(document.getElementById(ids.trigger.get()));
 	});
 
 	function handleClose() {
 		open.set(false);
-		const triggerEl = document.getElementById(get(ids.trigger));
-		handleFocus({ prop: get(closeFocus), defaultEl: triggerEl });
+		const triggerEl = document.getElementById(ids.trigger.get());
+		handleFocus({ prop: closeFocus.get(), defaultEl: triggerEl });
 	}
 
 	const isVisible = derivedVisible({ open, activeTrigger, forceVisible });
@@ -181,10 +181,10 @@ export function createPopover(args?: CreatePopoverProps) {
 	}
 
 	function handleClickOutside(e: PointerEvent) {
-		get(onOutsideClick)?.(e);
+		onOutsideClick.get()?.(e);
 		if (e.defaultPrevented) return;
 		const target = e.target;
-		const triggerEl = document.getElementById(get(ids.trigger));
+		const triggerEl = document.getElementById(ids.trigger.get());
 
 		if (triggerEl && isElement(target)) {
 			if (target === triggerEl || triggerEl.contains(target)) return;
@@ -267,7 +267,7 @@ export function createPopover(args?: CreatePopoverProps) {
 		if ($open) {
 			if (!$activeTrigger) {
 				tick().then(() => {
-					const triggerEl = document.getElementById(get(ids.trigger));
+					const triggerEl = document.getElementById(ids.trigger.get());
 					if (!isHTMLElement(triggerEl)) return;
 					activeTrigger.set(triggerEl);
 				});
@@ -277,8 +277,8 @@ export function createPopover(args?: CreatePopoverProps) {
 				unsubs.push(removeScroll());
 			}
 
-			const triggerEl = $activeTrigger ?? document.getElementById(get(ids.trigger));
-			handleFocus({ prop: get(openFocus), defaultEl: triggerEl });
+			const triggerEl = $activeTrigger ?? document.getElementById(ids.trigger.get());
+			handleFocus({ prop: openFocus.get(), defaultEl: triggerEl });
 		}
 
 		return () => {
diff --git a/src/lib/builders/radio-group/create.ts b/src/lib/builders/radio-group/create.ts
index 1c693bc4..edac3f04 100644
--- a/src/lib/builders/radio-group/create.ts
+++ b/src/lib/builders/radio-group/create.ts
@@ -17,7 +17,7 @@ import {
 } from '$lib/internal/helpers/index.js';
 import { safeOnMount } from '$lib/internal/helpers/lifecycle.js';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
-import { derived, get, writable } from 'svelte/store';
+import { derived, writable } from 'svelte/store';
 import type { RadioGroupEvents } from './events.js';
 import type { CreateRadioGroupProps, RadioGroupItemProps } from './types.js';
 
@@ -133,8 +133,8 @@ export function createRadioGroup(props?: CreateRadioGroupProps) {
 					const currentIndex = items.indexOf(el);
 
 					const dir = getElemDirection(root);
-					const { nextKey, prevKey } = getDirectionalKeys(dir, get(orientation));
-					const $loop = get(loop);
+					const { nextKey, prevKey } = getDirectionalKeys(dir, orientation.get());
+					const $loop = loop.get();
 
 					let itemToFocus: HTMLElement | null = null;
 					if (e.key === nextKey) {
diff --git a/src/lib/builders/range-calendar/create.ts b/src/lib/builders/range-calendar/create.ts
index 965af956..bd011ccc 100644
--- a/src/lib/builders/range-calendar/create.ts
+++ b/src/lib/builders/range-calendar/create.ts
@@ -3,47 +3,48 @@ import {
 	builder,
 	createElHelpers,
 	effect,
+	executeCallbacks,
 	generateIds,
 	isBrowser,
 	isHTMLElement,
+	isValidIndex,
 	kbd,
-	toWritableStores,
 	omit,
-	executeCallbacks,
-	styleToString,
 	overridable,
-	isValidIndex,
+	styleToString,
+	toWritableStores,
 } from '$lib/internal/helpers/index.js';
 
-import { derived, get, writable } from 'svelte/store';
-import type { CreateRangeCalendarProps } from './types.js';
-import { tick } from 'svelte';
 import {
-	getAnnouncer,
-	isBefore,
-	isBetweenInclusive,
-	toDate,
-	dateStore,
-	createFormatter,
-	getDefaultDate,
-	parseStringToDateValue,
 	areAllDaysBetweenValid,
-	isCalendarCell,
-	type Month,
+	createFormatter,
 	createMonths,
+	dateStore,
+	getAnnouncer,
+	getDefaultDate,
 	getSelectableCells,
 	isAfter,
+	isBefore,
+	isBetweenInclusive,
+	isCalendarCell,
+	parseStringToDateValue,
 	setPlaceholderToNodeValue,
+	toDate,
+	type Month,
 } from '$lib/internal/helpers/date/index.js';
+import { withGet } from '$lib/internal/helpers/withGet.js';
+import type { MeltActionReturn } from '$lib/internal/types.js';
 import {
-	type DateValue,
 	getLocalTimeZone,
-	isToday,
-	isSameMonth,
 	isSameDay,
+	isSameMonth,
+	isToday,
+	type DateValue,
 } from '@internationalized/date';
+import { tick } from 'svelte';
+import { derived, writable } from 'svelte/store';
 import type { RangeCalendarEvents } from './events.js';
-import type { MeltActionReturn } from '$lib/internal/types.js';
+import type { CreateRangeCalendarProps } from './types.js';
 
 const defaults = {
 	isDateDisabled: undefined,
@@ -107,17 +108,20 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 		defaultValue: withDefaults.defaultValue?.start,
 		defaultPlaceholder: withDefaults.defaultPlaceholder,
 	});
-	const formatter = createFormatter(get(locale));
+	const formatter = createFormatter(locale.get());
 	const valueWritable = withDefaults.value ?? writable(withDefaults.defaultValue);
 	const value = overridable(valueWritable, withDefaults.onValueChange);
 
-	const defaultStart = withDefaults.value ? get(withDefaults.value)?.start : undefined;
-	const startValue = writable<DateValue | undefined>(
-		defaultStart ?? withDefaults.defaultValue?.start
-	);
+	if (!value.get()) {
+		value.set(withDefaults.defaultValue);
+	}
 
-	const defaultEnd = withDefaults.value ? get(withDefaults.value)?.end : undefined;
-	const endValue = writable<DateValue | undefined>(defaultEnd ?? withDefaults.defaultValue?.end);
+	const startValue = withGet(
+		writable<DateValue | undefined>(value.get().start ?? withDefaults.defaultValue?.start)
+	);
+	const endValue = withGet(
+		writable<DateValue | undefined>(value.get().end ?? withDefaults.defaultValue?.end)
+	);
 
 	const placeholderWritable =
 		withDefaults.placeholder ?? writable(withDefaults.defaultPlaceholder ?? defaultDate);
@@ -126,18 +130,20 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 		withDefaults.defaultPlaceholder ?? defaultDate
 	);
 
-	const focusedValue = writable<DateValue | null>(null);
+	const focusedValue = withGet(writable<DateValue | null>(null));
 
-	const lastPressedDateValue = writable<DateValue | null>(null);
+	const lastPressedDateValue = withGet(writable<DateValue | null>(null));
 
-	const months = writable<Month<DateValue>[]>(
-		createMonths({
-			dateObj: get(placeholder),
-			weekStartsOn: withDefaults.weekStartsOn,
-			locale: withDefaults.locale,
-			fixedWeeks: withDefaults.fixedWeeks,
-			numberOfMonths: withDefaults.numberOfMonths,
-		})
+	const months = withGet(
+		writable<Month<DateValue>[]>(
+			createMonths({
+				dateObj: placeholder.get(),
+				weekStartsOn: withDefaults.weekStartsOn,
+				locale: withDefaults.locale,
+				fixedWeeks: withDefaults.fixedWeeks,
+				numberOfMonths: withDefaults.numberOfMonths,
+			})
+		)
 	);
 
 	/**
@@ -145,37 +151,45 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 	 * which we use to determine how keyboard navigation and if we should apply
 	 * `data-outside-month` to cells.
 	 */
-	const visibleMonths = derived([months], ([$months]) => {
-		return $months.map((month) => {
-			return month.value;
-		});
-	});
+	const visibleMonths = withGet(
+		derived([months], ([$months]) => {
+			return $months.map((month) => {
+				return month.value;
+			});
+		})
+	);
 
-	const isOutsideVisibleMonths = derived([visibleMonths], ([$visibleMonths]) => {
-		return (date: DateValue) => {
-			return !$visibleMonths.some((month) => isSameMonth(date, month));
-		};
-	});
+	const isOutsideVisibleMonths = withGet(
+		derived([visibleMonths], ([$visibleMonths]) => {
+			return (date: DateValue) => {
+				return !$visibleMonths.some((month) => isSameMonth(date, month));
+			};
+		})
+	);
 
-	const isDateDisabled = derived(
-		[options.isDateDisabled, minValue, maxValue],
-		([$isDateDisabled, $minValue, $maxValue]) => {
+	const isDateDisabled = withGet(
+		derived(
+			[options.isDateDisabled, minValue, maxValue],
+			([$isDateDisabled, $minValue, $maxValue]) => {
+				return (date: DateValue) => {
+					if ($isDateDisabled?.(date)) return true;
+					if ($minValue && isBefore(date, $minValue)) return true;
+					if ($maxValue && isAfter(date, $maxValue)) return true;
+					return false;
+				};
+			}
+		)
+	);
+
+	const isDateUnavailable = withGet(
+		derived([options.isDateUnavailable], ([$isDateUnavailable]) => {
 			return (date: DateValue) => {
-				if ($isDateDisabled?.(date)) return true;
-				if ($minValue && isBefore(date, $minValue)) return true;
-				if ($maxValue && isAfter(date, $maxValue)) return true;
+				if ($isDateUnavailable?.(date)) return true;
 				return false;
 			};
-		}
+		})
 	);
 
-	const isDateUnavailable = derived([options.isDateUnavailable], ([$isDateUnavailable]) => {
-		return (date: DateValue) => {
-			if ($isDateUnavailable?.(date)) return true;
-			return false;
-		};
-	});
-
 	const isStartInvalid = derived(
 		[startValue, isDateUnavailable, isDateDisabled],
 		([$startValue, $isDateUnavailable, $isDateDisabled]) => {
@@ -204,7 +218,7 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 		}
 	);
 
-	const isNextButtonDisabled = derived(
+	const isNextButtonDisabled = withGet.derived(
 		[months, maxValue, disabled],
 		([$months, $maxValue, $disabled]) => {
 			if (!$maxValue || !$months.length) return false;
@@ -215,7 +229,7 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 		}
 	);
 
-	const isPrevButtonDisabled = derived(
+	const isPrevButtonDisabled = withGet.derived(
 		[months, minValue, disabled],
 		([$months, $minValue, $disabled]) => {
 			if (!$minValue || !$months.length) return false;
@@ -228,7 +242,7 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 
 	let announcer = getAnnouncer();
 
-	const headingValue = derived([months, locale], ([$months, $locale]) => {
+	const headingValue = withGet.derived([months, locale], ([$months, $locale]) => {
 		if (!$months.length) return '';
 		if ($locale !== formatter.getLocale()) {
 			formatter.setLocale($locale);
@@ -254,7 +268,7 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 		return content;
 	});
 
-	const fullCalendarLabel = derived(
+	const fullCalendarLabel = withGet.derived(
 		[headingValue, calendarLabel],
 		([$headingValue, $calendarLabel]) => {
 			return `${$calendarLabel}, ${$headingValue}`;
@@ -279,7 +293,7 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 			 * when the grid is mounted. The label is updated
 			 * via an effect when the active date or label changes.
 			 */
-			createAccessibleHeading(node, get(fullCalendarLabel));
+			createAccessibleHeading(node, fullCalendarLabel.get());
 			announcer = getAnnouncer();
 
 			const unsubKb = addMeltEventListener(node, 'keydown', handleCalendarKeydown);
@@ -387,7 +401,7 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 		};
 	});
 
-	const highlightedRange = derived(
+	const highlightedRange = withGet.derived(
 		[startValue, endValue, focusedValue, isDateDisabled, isDateUnavailable],
 		([$startValue, $endValue, $focusedValue, $isDateDisabled, $isDateUnavailable]) => {
 			if ($startValue && $endValue) return null;
@@ -498,19 +512,19 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 					const args = getElArgs();
 					if (args.disabled) return;
 					if (!args.value) return;
-					handleCellClick(e, parseStringToDateValue(args.value, get(placeholder)));
+					handleCellClick(e, parseStringToDateValue(args.value, placeholder.get()));
 				}),
 				addMeltEventListener(node, 'mouseenter', () => {
 					const args = getElArgs();
 					if (args.disabled) return;
 					if (!args.value) return;
-					focusedValue.set(parseStringToDateValue(args.value, get(placeholder)));
+					focusedValue.set(parseStringToDateValue(args.value, placeholder.get()));
 				}),
 				addMeltEventListener(node, 'focusin', () => {
 					const args = getElArgs();
 					if (args.disabled) return;
 					if (!args.value) return;
-					focusedValue.set(parseStringToDateValue(args.value, get(placeholder)));
+					focusedValue.set(parseStringToDateValue(args.value, placeholder.get()));
 				})
 			);
 
@@ -534,7 +548,7 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 		([$placeholder, $weekStartsOn, $locale, $fixedWeeks, $numberOfMonths]) => {
 			if (!isBrowser || !$placeholder) return;
 
-			const $visibleMonths = get(visibleMonths);
+			const $visibleMonths = visibleMonths.get();
 
 			/**
 			 * If the placeholder's month is already in the visible months,
@@ -566,13 +580,13 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 	 */
 	effect([fullCalendarLabel], ([$fullCalendarLabel]) => {
 		if (!isBrowser) return;
-		const node = document.getElementById(get(ids.accessibleHeading));
+		const node = document.getElementById(ids.accessibleHeading.get());
 		if (!isHTMLElement(node)) return;
 		node.textContent = $fullCalendarLabel;
 	});
 
 	effect([startValue], ([$startValue]) => {
-		if ($startValue && get(placeholder) !== $startValue) {
+		if ($startValue && placeholder.get() !== $startValue) {
 			placeholder.set($startValue);
 		}
 	});
@@ -617,7 +631,7 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 		});
 		const h2 = document.createElement('div');
 		h2.textContent = label;
-		h2.id = get(ids.accessibleHeading);
+		h2.id = ids.accessibleHeading.get();
 		h2.role = 'heading';
 		h2.ariaLevel = '2';
 		node.insertBefore(div, node.firstChild);
@@ -645,18 +659,18 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 	 * ```
 	 */
 	function nextPage() {
-		const $months = get(months);
-		const $numberOfMonths = get(numberOfMonths);
-		if (get(pagedNavigation)) {
+		const $months = months.get();
+		const $numberOfMonths = numberOfMonths.get();
+		if (pagedNavigation.get()) {
 			const firstMonth = $months[0].value;
 			placeholder.set(firstMonth.add({ months: $numberOfMonths }));
 		} else {
 			const firstMonth = $months[0].value;
 			const newMonths = createMonths({
 				dateObj: firstMonth.add({ months: 1 }),
-				weekStartsOn: get(weekStartsOn),
-				locale: get(locale),
-				fixedWeeks: get(fixedWeeks),
+				weekStartsOn: weekStartsOn.get(),
+				locale: locale.get(),
+				fixedWeeks: fixedWeeks.get(),
 				numberOfMonths: $numberOfMonths,
 			});
 
@@ -686,18 +700,18 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 	 * ```
 	 */
 	function prevPage() {
-		const $months = get(months);
-		const $numberOfMonths = get(numberOfMonths);
-		if (get(pagedNavigation)) {
+		const $months = months.get();
+		const $numberOfMonths = numberOfMonths.get();
+		if (pagedNavigation.get()) {
 			const firstMonth = $months[0].value;
 			placeholder.set(firstMonth.subtract({ months: $numberOfMonths }));
 		} else {
 			const firstMonth = $months[0].value;
 			const newMonths = createMonths({
 				dateObj: firstMonth.subtract({ months: 1 }),
-				weekStartsOn: get(weekStartsOn),
-				locale: get(locale),
-				fixedWeeks: get(fixedWeeks),
+				weekStartsOn: weekStartsOn.get(),
+				locale: locale.get(),
+				fixedWeeks: fixedWeeks.get(),
 				numberOfMonths: $numberOfMonths,
 			});
 
@@ -742,18 +756,18 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 	}
 
 	function handleCellClick(e: Event, date: DateValue) {
-		const $isDateDisabled = get(isDateDisabled);
-		const $isDateUnavailable = get(isDateUnavailable);
+		const $isDateDisabled = isDateDisabled.get();
+		const $isDateUnavailable = isDateUnavailable.get();
 		if ($isDateDisabled(date) || $isDateUnavailable(date)) return;
-		const $lastPressedDate = get(lastPressedDateValue);
+		const $lastPressedDate = lastPressedDateValue.get();
 		lastPressedDateValue.set(date);
 
-		const $startValue = get(startValue);
-		const $endValue = get(endValue);
-		const $highlightedRange = get(highlightedRange);
+		const $startValue = startValue.get();
+		const $endValue = endValue.get();
+		const $highlightedRange = highlightedRange.get();
 
 		if ($startValue && $highlightedRange === null) {
-			if (isSameDay($startValue, date) && !get(preventDeselect) && !$endValue) {
+			if (isSameDay($startValue, date) && !preventDeselect.get() && !$endValue) {
 				startValue.set(undefined);
 				placeholder.set(date);
 				announcer.announce('Selected date is now empty.', 'polite');
@@ -768,7 +782,7 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 			}
 		}
 
-		if ($startValue && isSameDay($startValue, date) && !get(preventDeselect) && !$endValue) {
+		if ($startValue && isSameDay($startValue, date) && !preventDeselect.get() && !$endValue) {
 			startValue.set(undefined);
 			placeholder.set(date);
 			announcer.announce('Selected date is now empty.', 'polite');
@@ -827,12 +841,12 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 			const cellValue = currentCell.getAttribute('data-value');
 			if (!cellValue) return;
 
-			handleCellClick(e, parseStringToDateValue(cellValue, get(placeholder)));
+			handleCellClick(e, parseStringToDateValue(cellValue, placeholder.get()));
 		}
 	}
 
 	function shiftFocus(node: HTMLElement, add: number) {
-		const $calendarId = get(ids.calendar);
+		const $calendarId = ids.calendar.get();
 		const candidateCells = getSelectableCells($calendarId);
 		if (!candidateCells.length) {
 			return;
@@ -867,11 +881,11 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 			 */
 
 			// shift the calendar back a month unless previous month is disabled
-			if (get(isPrevButtonDisabled)) return;
+			if (isPrevButtonDisabled.get()) return;
 
-			const $months = get(months);
+			const $months = months.get();
 			const firstMonth = $months[0].value;
-			const $numberOfMonths = get(numberOfMonths);
+			const $numberOfMonths = numberOfMonths.get();
 			placeholder.set(firstMonth.subtract({ months: $numberOfMonths }));
 
 			// Without a tick here, it seems to be too fast for
@@ -903,11 +917,11 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 			 */
 
 			// shift the calendar forward a month unless next month is disabled
-			if (get(isNextButtonDisabled)) return;
+			if (isNextButtonDisabled.get()) return;
 
-			const $months = get(months);
+			const $months = months.get();
 			const firstMonth = $months[0].value;
-			const $numberOfMonths = get(numberOfMonths);
+			const $numberOfMonths = numberOfMonths.get();
 			placeholder.set(firstMonth.add({ months: $numberOfMonths }));
 
 			tick().then(() => {
@@ -978,8 +992,8 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 	 */
 
 	effect([value], ([$value]) => {
-		const $startValue = get(startValue);
-		const $endValue = get(endValue);
+		const $startValue = startValue.get();
+		const $endValue = endValue.get();
 
 		if ($value?.start && $value?.end) {
 			if ($value.start !== $startValue) {
@@ -993,7 +1007,7 @@ export function createRangeCalendar<T extends DateValue = DateValue>(
 	});
 
 	effect([startValue, endValue], ([$startValue, $endValue]) => {
-		const $value = get(value);
+		const $value = value.get();
 
 		if ($value && $value?.start === $startValue && $value?.end === $endValue) return;
 
diff --git a/src/lib/builders/slider/create.ts b/src/lib/builders/slider/create.ts
index d56f992e..8f961360 100644
--- a/src/lib/builders/slider/create.ts
+++ b/src/lib/builders/slider/create.ts
@@ -20,9 +20,10 @@ import {
 	type StyleObject,
 } from '$lib/internal/helpers/index.js';
 import type { MeltActionReturn, NonEmptyArray } from '$lib/internal/types.js';
-import { derived, get, writable } from 'svelte/store';
+import { derived, writable } from 'svelte/store';
 import type { SliderEvents } from './events.js';
 
+import { withGet } from '$lib/internal/helpers/withGet.js';
 import type { CreateSliderProps } from './types.js';
 
 const defaults = {
@@ -46,9 +47,9 @@ export const createSlider = (props?: CreateSliderProps) => {
 	const valueWritable = withDefaults.value ?? writable(withDefaults.defaultValue);
 	const value = overridable(valueWritable, withDefaults?.onValueChange);
 
-	const isActive = writable(false);
-	const currentThumbIndex = writable<number>(0);
-	const activeThumb = writable<{ thumb: HTMLElement; index: number } | null>(null);
+	const isActive = withGet(writable(false));
+	const currentThumbIndex = withGet(writable<number>(0));
+	const activeThumb = withGet(writable<{ thumb: HTMLElement; index: number } | null>(null));
 
 	const meltIds = generateIds(['root'] as const);
 
@@ -76,9 +77,9 @@ export const createSlider = (props?: CreateSliderProps) => {
 				swap();
 				return newValue;
 			}
-			const $min = get(min);
-			const $max = get(max);
-			const $step = get(step);
+			const $min = min.get();
+			const $max = max.get();
+			const $step = step.get();
 			newValue[index] = snapValueToStep(val, $min, $max, $step);
 
 			return newValue;
@@ -102,7 +103,7 @@ export const createSlider = (props?: CreateSliderProps) => {
 		};
 	});
 
-	const direction = derived([orientation, dir], ([$orientation, $dir]) => {
+	const direction = withGet.derived([orientation, dir], ([$orientation, $dir]) => {
 		if ($orientation === 'horizontal') {
 			return $dir === 'rtl' ? 'rl' : 'lr';
 		} else {
@@ -171,7 +172,7 @@ export const createSlider = (props?: CreateSliderProps) => {
 		stores: [value, position, min, max, disabled, orientation, direction],
 		returned: ([$value, $position, $min, $max, $disabled, $orientation, $direction]) => {
 			const result = Array.from({ length: $value.length || 1 }, (_, i) => {
-				const currentThumb = get(currentThumbIndex);
+				const currentThumb = currentThumbIndex.get();
 
 				if (currentThumb < $value.length) {
 					currentThumbIndex.update((prev) => prev + 1);
@@ -226,7 +227,7 @@ export const createSlider = (props?: CreateSliderProps) => {
 		},
 		action: (node: HTMLElement): MeltActionReturn<SliderEvents['thumb']> => {
 			const unsub = addMeltEventListener(node, 'keydown', (event) => {
-				if (get(disabled)) return;
+				if (disabled.get()) return;
 
 				const target = event.currentTarget;
 				if (!isHTMLElement(target)) return;
@@ -251,12 +252,12 @@ export const createSlider = (props?: CreateSliderProps) => {
 
 				event.preventDefault();
 
-				const $min = get(min);
-				const $max = get(max);
-				const $step = get(step);
-				const $value = get(value);
-				const $orientation = get(orientation);
-				const $direction = get(direction);
+				const $min = min.get();
+				const $max = max.get();
+				const $step = step.get();
+				const $value = value.get();
+				const $orientation = orientation.get();
+				const $direction = direction.get();
 				const thumbValue = $value[index];
 
 				switch (event.key) {
@@ -457,12 +458,12 @@ export const createSlider = (props?: CreateSliderProps) => {
 			};
 
 			const pointerMove = (e: PointerEvent) => {
-				if (!get(isActive)) return;
+				if (!isActive.get()) return;
 				e.preventDefault();
 				e.stopPropagation();
 
 				const sliderEl = getElementByMeltId($root['data-melt-id']);
-				const closestThumb = get(activeThumb);
+				const closestThumb = activeThumb.get();
 				if (!sliderEl || !closestThumb) return;
 
 				closestThumb.thumb.focus();
diff --git a/src/lib/builders/switch/create.ts b/src/lib/builders/switch/create.ts
index 6469c5d7..282b4b2a 100644
--- a/src/lib/builders/switch/create.ts
+++ b/src/lib/builders/switch/create.ts
@@ -10,7 +10,7 @@ import {
 	toWritableStores,
 } from '$lib/internal/helpers/index.js';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
-import { get, writable } from 'svelte/store';
+import { writable } from 'svelte/store';
 import { executeCallbacks } from '../../internal/helpers/callbacks.js';
 import type { SwitchEvents } from './events.js';
 import type { CreateSwitchProps } from './types.js';
@@ -35,7 +35,7 @@ export function createSwitch(props?: CreateSwitchProps) {
 	const checked = overridable(checkedWritable, propsWithDefaults?.onCheckedChange);
 
 	function toggleSwitch() {
-		if (get(disabled)) return;
+		if (disabled.get()) return;
 		checked.update((prev) => !prev);
 	}
 
diff --git a/src/lib/builders/table-of-contents/create.ts b/src/lib/builders/table-of-contents/create.ts
index 7dfb10a0..b05d4ddb 100644
--- a/src/lib/builders/table-of-contents/create.ts
+++ b/src/lib/builders/table-of-contents/create.ts
@@ -7,9 +7,10 @@ import {
 import type { Defaults } from '$lib/internal/types';
 
 import { dequal } from 'dequal';
-import { derived, get, writable, type Writable } from 'svelte/store';
+import { derived, writable } from 'svelte/store';
 
 import { safeOnMount } from '$lib/internal/helpers/lifecycle';
+import { withGet } from '$lib/internal/helpers/withGet';
 import type {
 	CreateTableOfContentsArgs,
 	ElementHeadingLU,
@@ -48,9 +49,9 @@ export function createTableOfContents(args: CreateTableOfContentsArgs) {
 	/** Lookup to see which parent headings a heading has. */
 	let headingParentsLU: HeadingParentsLU = {};
 	/** List of the active parent indexes. */
-	const activeParentIdxs: Writable<number[]> = writable([]);
+	const activeParentIdxs = withGet.writable<number[]>([]);
 	/** List of the indexes of the visible elements. */
-	const visibleElementIdxs: Writable<number[]> = writable([]);
+	const visibleElementIdxs = withGet.writable<number[]>([]);
 
 	let elementTarget: Element | null = null;
 
@@ -60,8 +61,8 @@ export function createTableOfContents(args: CreateTableOfContentsArgs) {
 	const observer_threshold = 0.01;
 
 	// Stores
-	const activeHeadingIdxs: Writable<number[]> = writable([]);
-	const headingsTree: Writable<TableOfContentsItem[]> = writable([]);
+	const activeHeadingIdxs = withGet(writable<number[]>([]));
+	const headingsTree = withGet(writable<TableOfContentsItem[]>([]));
 
 	// Helpers
 	function generateInitialLists(elementTarget: Element) {
@@ -181,7 +182,7 @@ export function createTableOfContents(args: CreateTableOfContentsArgs) {
 			const el_idx = elementsList.indexOf(<HTMLElement>entries[i].target);
 			const toc_idx = elementHeadingLU[el_idx];
 
-			let tempVisibleElementIdxs = get(visibleElementIdxs);
+			let tempVisibleElementIdxs = visibleElementIdxs.get();
 
 			if (entries[i].intersectionRatio >= observer_threshold) {
 				// Only add the observed element to the visibleElementIdxs list if it isn't added yet.
@@ -217,7 +218,7 @@ export function createTableOfContents(args: CreateTableOfContentsArgs) {
 		}
 
 		const allActiveHeaderIdxs = Array.from(
-			new Set(get(visibleElementIdxs).map((idx) => elementHeadingLU[idx]))
+			new Set(visibleElementIdxs.get().map((idx) => elementHeadingLU[idx]))
 		);
 
 		let activeHeaderIdxs: number[];
diff --git a/src/lib/builders/tabs/create.ts b/src/lib/builders/tabs/create.ts
index c78d7e18..4a147097 100644
--- a/src/lib/builders/tabs/create.ts
+++ b/src/lib/builders/tabs/create.ts
@@ -17,7 +17,7 @@ import {
 	toWritableStores,
 } from '$lib/internal/helpers/index.js';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
-import { get, writable } from 'svelte/store';
+import { writable } from 'svelte/store';
 import type { TabsEvents } from './events.js';
 import type { CreateTabsProps, TabsTriggerProps } from './types.js';
 
@@ -42,7 +42,7 @@ export function createTabs(props?: CreateTabsProps) {
 	const valueWritable = withDefaults.value ?? writable(withDefaults.defaultValue);
 	const value = overridable(valueWritable, withDefaults?.onValueChange);
 
-	let ssrValue = withDefaults.defaultValue ?? get(value);
+	let ssrValue = withDefaults.defaultValue ?? value.get();
 
 	// Root
 	const root = builder(name(), {
@@ -107,7 +107,7 @@ export function createTabs(props?: CreateTabsProps) {
 					const disabled = node.dataset.disabled === 'true';
 					const tabValue = node.dataset.value;
 
-					if (get(activateOnFocus) && !disabled && tabValue !== undefined) {
+					if (activateOnFocus.get() && !disabled && tabValue !== undefined) {
 						value.set(tabValue);
 					}
 				}),
@@ -137,7 +137,7 @@ export function createTabs(props?: CreateTabsProps) {
 					const rootEl = el.closest(selector());
 					if (!isHTMLElement(rootEl)) return;
 
-					const $loop = get(loop);
+					const $loop = loop.get();
 
 					const triggers = Array.from(rootEl.querySelectorAll('[role="tab"]')).filter(
 						(trigger): trigger is HTMLElement => isHTMLElement(trigger)
@@ -146,7 +146,7 @@ export function createTabs(props?: CreateTabsProps) {
 					const triggerIdx = enabledTriggers.findIndex((el) => el === e.target);
 
 					const dir = getElemDirection(rootEl);
-					const { nextKey, prevKey } = getDirectionalKeys(dir, get(orientation));
+					const { nextKey, prevKey } = getDirectionalKeys(dir, orientation.get());
 
 					if (e.key === nextKey) {
 						e.preventDefault();
diff --git a/src/lib/builders/tags-input/create.ts b/src/lib/builders/tags-input/create.ts
index 1c0b2970..cd6c6613 100644
--- a/src/lib/builders/tags-input/create.ts
+++ b/src/lib/builders/tags-input/create.ts
@@ -1,6 +1,8 @@
 import {
+	addMeltEventListener,
 	builder,
 	createElHelpers,
+	disabledAttr,
 	effect,
 	executeCallbacks,
 	generateId,
@@ -12,16 +14,15 @@ import {
 	overridable,
 	styleToString,
 	toWritableStores,
-	addMeltEventListener,
-	disabledAttr,
 } from '$lib/internal/helpers/index.js';
+import { withGet } from '$lib/internal/helpers/withGet';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
-import { derived, get, readonly, writable } from 'svelte/store';
-import { focusInput, highlightText, setSelectedFromEl } from './helpers.js';
-import type { CreateTagsInputProps, Tag, TagProps } from './types.js';
 import { tick } from 'svelte';
-import type { TagsInputEvents } from './events.js';
+import { derived, readonly, writable } from 'svelte/store';
 import { generateIds } from '../../internal/helpers/id';
+import type { TagsInputEvents } from './events.js';
+import { focusInput, highlightText, setSelectedFromEl } from './helpers.js';
+import type { CreateTagsInputProps, Tag, TagProps } from './types.js';
 
 const defaults = {
 	placeholder: '',
@@ -94,23 +95,23 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 	const tags = overridable<Tag[]>(tagsWritable, withDefaults?.onTagsChange);
 
 	// Selected tag store. When `null`, no tag is selected
-	const selected = writable<Tag | null>(withDefaults.selected ?? null);
+	const selected = withGet.writable<Tag | null>(withDefaults.selected ?? null);
 
-	const editing = writable<Tag | null>(null);
+	const editing = withGet.writable<Tag | null>(null);
 
 	// Run validation checks and if a validation fails return false immediately
 	const isInputValid = (v: string) => {
-		const $tags = get(tags);
-		const $editing = get(editing);
-		const $allowed = get(allowed);
-		const $denied = get(denied);
-		const $maxTags = get(maxTags);
+		const $tags = tags.get();
+		const $editing = editing.get();
+		const $allowed = allowed.get();
+		const $denied = denied.get();
+		const $maxTags = maxTags.get();
 
 		// Trim the validation value before validations
-		if (get(trim)) v = v.trim();
+		if (trim.get()) v = v.trim();
 
 		// Tag uniqueness
-		if (get(unique) && $editing?.value !== v) {
+		if (unique.get() && $editing?.value !== v) {
 			const index = $tags.findIndex((tag) => tag.value === v);
 			if (index >= 0) return false;
 		}
@@ -128,7 +129,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 
 	// Add a tag to the $tags store. Calls `$options.add()` if set
 	const addTag = async (v: string) => {
-		const $add = get(add);
+		const $add = add.get();
 
 		let workingTag = { id: '', value: v };
 
@@ -148,7 +149,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 		}
 
 		// Trim the value, only after the user defined add function
-		if (get(trim)) workingTag.value = workingTag.value.trim();
+		if (trim.get()) workingTag.value = workingTag.value.trim();
 
 		// if it's not valid we don't add it to the tags list
 		if (!isInputValid(workingTag.value)) return false;
@@ -162,7 +163,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 
 	// Update a tag in the $tags store. Calls `$options.update()` if set
 	async function updateTag(tag: Tag, select = false) {
-		const $update = get(update);
+		const $update = update.get();
 
 		// Store the id, incase it changes during the update
 		const oldId = tag.id;
@@ -182,7 +183,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 		}
 
 		// Trim the value, only after the user defined update function
-		if (get(trim)) workingTag.value = workingTag.value.trim();
+		if (trim.get()) workingTag.value = workingTag.value.trim();
 
 		// if it's not valid we don't add it to the tags list
 		if (!isInputValid(workingTag.value)) return false;
@@ -205,7 +206,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 
 	// Remove a tag from the $tags store. Calls `$options.remove()` if set
 	async function removeTag(t: Tag) {
-		const $remove = get(remove);
+		const $remove = remove.get();
 
 		if ($remove) {
 			try {
@@ -215,7 +216,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 			}
 		}
 
-		const $tags = get(tags);
+		const $tags = tags.get();
 		const index = $tags.findIndex((tag) => tag.id === t.id);
 		tags.update((t) => {
 			t.splice(index, 1);
@@ -310,7 +311,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 					if (!value) return;
 
 					// Handle clear or add (if set)
-					const $blur = get(blur);
+					const $blur = blur.get();
 
 					if ($blur === 'clear') {
 						node.value = '';
@@ -328,7 +329,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 					if (!pastedText) return;
 
 					// Do nothing when addOnPaste is false
-					if (!get(addOnPaste)) return;
+					if (!addOnPaste.get()) return;
 					e.preventDefault();
 
 					// Update value with the pasted text or set invalid
@@ -339,7 +340,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 					}
 				}),
 				addMeltEventListener(node, 'keydown', async (e) => {
-					const $selected = get(selected);
+					const $selected = selected.get();
 
 					if ($selected) {
 						// Check if a character is entered into the input
@@ -511,7 +512,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 			const unsub = executeCallbacks(
 				addMeltEventListener(node, 'mousedown', (e) => {
 					// Do nothing when editing any tag
-					const $editing = get(editing);
+					const $editing = editing.get();
 					if ($editing && $editing.id !== getElProps().id) return;
 
 					// Focus on the input and set this as the selected tag
@@ -522,7 +523,7 @@ export function createTagsInput(props?: CreateTagsInputProps) {
 				}),
 				addMeltEventListener(node, 'click', (e) => {
 					// Do nothing when editing any tag
-					const $editing = get(editing);
+					const $editing = editing.get();
 					if ($editing && $editing.id === getElProps().id) return;
 
 					// Focus on the input and set this as the selected tag
diff --git a/src/lib/builders/toast/create.ts b/src/lib/builders/toast/create.ts
index 5e3bd8f9..ab3b4719 100644
--- a/src/lib/builders/toast/create.ts
+++ b/src/lib/builders/toast/create.ts
@@ -1,19 +1,19 @@
-import { derived, get, writable, readonly } from 'svelte/store';
+import { usePortal } from '$lib/internal/actions/index.js';
 import {
+	addMeltEventListener,
 	builder,
 	createElHelpers,
 	executeCallbacks,
 	generateId,
 	isTouch,
+	kbd,
 	noop,
 	toWritableStores,
-	addMeltEventListener,
-	kbd,
 } from '$lib/internal/helpers/index.js';
-import type { AddToastProps, CreateToasterProps, Toast } from './types.js';
-import { usePortal } from '$lib/internal/actions/index.js';
 import type { MeltActionReturn } from '$lib/internal/types.js';
+import { derived, readonly, writable } from 'svelte/store';
 import type { ToastEvents } from './events.js';
+import type { AddToastProps, CreateToasterProps, Toast } from './types.js';
 
 type ToastParts = 'content' | 'title' | 'description' | 'close';
 const { name } = createElHelpers<ToastParts>('toast');
@@ -33,8 +33,8 @@ export function createToaster<T = object>(props?: CreateToasterProps) {
 
 	const addToast = (props: AddToastProps<T>) => {
 		const propsWithDefaults = {
-			closeDelay: get(closeDelay),
-			type: get(type),
+			closeDelay: closeDelay.get(),
+			type: type.get(),
 			...props,
 		} satisfies AddToastProps<T>;
 
diff --git a/src/lib/builders/toggle-group/create.ts b/src/lib/builders/toggle-group/create.ts
index 5e2cba8c..5ca1ede7 100644
--- a/src/lib/builders/toggle-group/create.ts
+++ b/src/lib/builders/toggle-group/create.ts
@@ -14,7 +14,7 @@ import {
 	toWritableStores,
 } from '$lib/internal/helpers/index.js';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
-import { derived, get, writable } from 'svelte/store';
+import { derived, writable } from 'svelte/store';
 import type { ToggleGroupEvents } from './events.js';
 import type { CreateToggleGroupProps, ToggleGroupItemProps, ToggleGroupType } from './types.js';
 
@@ -89,7 +89,7 @@ export const createToggleGroup = <T extends ToggleGroupType = 'single'>(
 			if (!isHTMLElement(parentGroup)) return {};
 
 			const items = Array.from(parentGroup.querySelectorAll(selector('item')));
-			const $value = get(value);
+			const $value = value.get();
 			const anyPressed = Array.isArray($value) ? $value.length > 0 : $value !== null;
 
 			if (!anyPressed && items[0] === node) {
@@ -130,7 +130,7 @@ export const createToggleGroup = <T extends ToggleGroupType = 'single'>(
 						handleValueUpdate();
 						return;
 					}
-					if (!get(rovingFocus)) return;
+					if (!rovingFocus.get()) return;
 
 					const el = e.currentTarget;
 					if (!isHTMLElement(el)) return;
@@ -145,7 +145,7 @@ export const createToggleGroup = <T extends ToggleGroupType = 'single'>(
 					const currentIndex = items.indexOf(el);
 
 					const dir = getElemDirection(el);
-					const $orientation = get(orientation);
+					const $orientation = orientation.get();
 					const nextKey = {
 						horizontal: dir === 'rtl' ? kbd.ARROW_LEFT : kbd.ARROW_RIGHT,
 						vertical: kbd.ARROW_DOWN,
@@ -156,7 +156,7 @@ export const createToggleGroup = <T extends ToggleGroupType = 'single'>(
 						vertical: kbd.ARROW_UP,
 					}[$orientation ?? 'horizontal'];
 
-					const $loop = get(loop);
+					const $loop = loop.get();
 
 					if (e.key === nextKey) {
 						e.preventDefault();
diff --git a/src/lib/builders/toggle/create.ts b/src/lib/builders/toggle/create.ts
index 879a44eb..03b1d19c 100644
--- a/src/lib/builders/toggle/create.ts
+++ b/src/lib/builders/toggle/create.ts
@@ -9,7 +9,7 @@ import {
 	toWritableStores,
 } from '$lib/internal/helpers/index.js';
 import type { MeltActionReturn } from '$lib/internal/types.js';
-import { get, writable } from 'svelte/store';
+import { writable } from 'svelte/store';
 import type { ToggleEvents } from './events.js';
 import type { CreateToggleProps } from './types.js';
 
@@ -28,7 +28,7 @@ export function createToggle(props?: CreateToggleProps) {
 	const pressed = overridable(pressedWritable, withDefaults?.onPressedChange);
 
 	function handleToggle() {
-		const $disabled = get(disabled);
+		const $disabled = disabled.get();
 		if ($disabled) return;
 		pressed.update((v) => !v);
 	}
diff --git a/src/lib/builders/toolbar/create.ts b/src/lib/builders/toolbar/create.ts
index eae0ca67..2cc74d95 100644
--- a/src/lib/builders/toolbar/create.ts
+++ b/src/lib/builders/toolbar/create.ts
@@ -11,7 +11,7 @@ import {
 	toWritableStores,
 } from '$lib/internal/helpers/index.js';
 import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
-import { derived, get, writable } from 'svelte/store';
+import { derived, writable } from 'svelte/store';
 import type { ToolbarEvents } from './events.js';
 import type {
 	CreateToolbarGroupProps,
@@ -231,8 +231,8 @@ export const createToolbar = (props?: CreateToolbarProps) => {
 	}
 
 	function handleKeyDown(e: KeyboardEvent) {
-		const $orientation = get(orientation);
-		const $loop = get(loop);
+		const $orientation = orientation.get();
+		const $loop = loop.get();
 
 		const dir = 'ltr' as 'ltr' | 'rtl';
 		const nextKey = {
diff --git a/src/lib/builders/tooltip/create.ts b/src/lib/builders/tooltip/create.ts
index 5d5aa3de..e2aabc80 100644
--- a/src/lib/builders/tooltip/create.ts
+++ b/src/lib/builders/tooltip/create.ts
@@ -20,10 +20,10 @@ import {
 
 import { useFloating, usePortal } from '$lib/internal/actions/index.js';
 import type { MeltActionReturn } from '$lib/internal/types.js';
-import { derived, get, writable, type Writable } from 'svelte/store';
+import { derived, writable, type Writable } from 'svelte/store';
+import { generateIds } from '../../internal/helpers/id';
 import type { TooltipEvents } from './events.js';
 import type { CreateTooltipProps } from './types.js';
-import { generateIds } from '../../internal/helpers/id';
 
 const defaults = {
 	positioning: {
@@ -79,7 +79,7 @@ export function createTooltip(props?: CreateTooltipProps) {
 
 	const getEl = (part: keyof typeof ids) => {
 		if (!isBrowser) return null;
-		return document.getElementById(get(ids[part]));
+		return document.getElementById(ids[part].get());
 	};
 
 	let openTimeout: number | null = null;
@@ -97,7 +97,7 @@ export function createTooltip(props?: CreateTooltipProps) {
 				// Don't override the reason if it's already set.
 				openReason.update((prev) => prev ?? reason);
 				openTimeout = null;
-			}, get(openDelay));
+			}, openDelay.get());
 		}
 	}
 
@@ -122,7 +122,7 @@ export function createTooltip(props?: CreateTooltipProps) {
 				openReason.set(null);
 				if (isBlur) clickedTrigger = false;
 				closeTimeout = null;
-			}, get(closeDelay));
+			}, closeDelay.get());
 		}
 	}
 
@@ -141,7 +141,7 @@ export function createTooltip(props?: CreateTooltipProps) {
 		},
 		action: (node: HTMLElement): MeltActionReturn<TooltipEvents['trigger']> => {
 			const keydownHandler = (e: KeyboardEvent) => {
-				if (get(closeOnEscape) && e.key === kbd.ESCAPE) {
+				if (closeOnEscape.get() && e.key === kbd.ESCAPE) {
 					if (openTimeout) {
 						window.clearTimeout(openTimeout);
 						openTimeout = null;
@@ -153,7 +153,7 @@ export function createTooltip(props?: CreateTooltipProps) {
 
 			const unsub = executeCallbacks(
 				addMeltEventListener(node, 'pointerdown', () => {
-					const $closeOnPointerDown = get(closeOnPointerDown);
+					const $closeOnPointerDown = closeOnPointerDown.get();
 					if (!$closeOnPointerDown) return;
 					open.set(false);
 					clickedTrigger = true;
@@ -264,7 +264,7 @@ export function createTooltip(props?: CreateTooltipProps) {
 	let isMouseInTooltipArea = false;
 
 	effect(open, ($open) => {
-		const currentGroup = get(group);
+		const currentGroup = group.get();
 		if (currentGroup === undefined || currentGroup === false) {
 			return;
 		}
@@ -292,7 +292,9 @@ export function createTooltip(props?: CreateTooltipProps) {
 				const triggerEl = getEl('trigger');
 				if (!contentEl || !triggerEl) return;
 
-				const polygonElements = get(disableHoverableContent) ? [triggerEl] : [triggerEl, contentEl];
+				const polygonElements = disableHoverableContent.get()
+					? [triggerEl]
+					: [triggerEl, contentEl];
 				const polygon = makeHullFromElements(polygonElements);
 
 				isMouseInTooltipArea = pointInPolygon(
diff --git a/src/lib/internal/helpers/date/store.ts b/src/lib/internal/helpers/date/store.ts
index 2723a68e..2566cccc 100644
--- a/src/lib/internal/helpers/date/store.ts
+++ b/src/lib/internal/helpers/date/store.ts
@@ -10,6 +10,7 @@ import type {
 	Disambiguation,
 	TimeFields,
 } from '@internationalized/date';
+import { withGet } from '../withGet';
 
 type AnyDateTime = ZonedDateTime | CalendarDateTime;
 
@@ -33,7 +34,7 @@ type DerivedFields<T> = T extends AnyDateTime
  * @see [@internationalized/date](https://react-spectrum.adobe.com/internationalized/date/index.html)
  */
 export function dateStore<T extends DateValue>(store: Writable<T>, defaultValue: T) {
-	const { set, update, subscribe } = store;
+	const { set, update, subscribe, get } = withGet(store);
 
 	function add(duration: DerivedDuration<T>) {
 		update((d) => {
@@ -86,10 +87,12 @@ export function dateStore<T extends DateValue>(store: Writable<T>, defaultValue:
 			set,
 			subscribe,
 			update,
+			get,
 		};
 	}
 
 	return {
+		get,
 		set,
 		update,
 		subscribe,
diff --git a/src/lib/internal/helpers/index.ts b/src/lib/internal/helpers/index.ts
index a32a58b3..74202cd2 100644
--- a/src/lib/internal/helpers/index.ts
+++ b/src/lib/internal/helpers/index.ts
@@ -25,3 +25,4 @@ export * from './elements.js';
 export * from './ignore.js';
 export * from './focus.js';
 export * from './math.js';
+export * from './withGet.js';
diff --git a/src/lib/internal/helpers/is.ts b/src/lib/internal/helpers/is.ts
index 888bb006..e4adf374 100644
--- a/src/lib/internal/helpers/is.ts
+++ b/src/lib/internal/helpers/is.ts
@@ -73,5 +73,5 @@ export function isReadable(value: unknown): value is Readable<unknown> {
 }
 
 export function isWritable(value: unknown): value is Writable<unknown> {
-	return isReadable(value) && 'subscribe' in value;
+	return isReadable(value) && 'set' in value;
 }
diff --git a/src/lib/internal/helpers/lifecycle.ts b/src/lib/internal/helpers/lifecycle.ts
index 172aa378..c23486d3 100644
--- a/src/lib/internal/helpers/lifecycle.ts
+++ b/src/lib/internal/helpers/lifecycle.ts
@@ -4,7 +4,7 @@ export const safeOnMount = (fn: (...args: unknown[]) => unknown) => {
 	try {
 		onMount(fn);
 	} catch {
-		return fn();
+		return fn;
 	}
 };
 
@@ -12,6 +12,6 @@ export const safeOnDestroy = (fn: (...args: unknown[]) => unknown) => {
 	try {
 		onDestroy(fn);
 	} catch {
-		return fn();
+		return fn;
 	}
 };
diff --git a/src/lib/internal/helpers/overridable.ts b/src/lib/internal/helpers/overridable.ts
index 55e53715..47035fde 100644
--- a/src/lib/internal/helpers/overridable.ts
+++ b/src/lib/internal/helpers/overridable.ts
@@ -1,8 +1,11 @@
 import type { Updater, Writable } from 'svelte/store';
+import { withGet } from './withGet';
 
 export type ChangeFn<T> = (args: { curr: T; next: T }) => T;
 
-export const overridable = <T>(store: Writable<T>, onChange?: ChangeFn<T>) => {
+export const overridable = <T>(_store: Writable<T>, onChange?: ChangeFn<T>) => {
+	const store = withGet(_store);
+
 	const update = (updater: Updater<T>, sideEffect?: (newValue: T) => void) => {
 		store.update((curr) => {
 			const next = updater(curr);
diff --git a/src/lib/internal/helpers/store/derivedWithUnsubscribe.ts b/src/lib/internal/helpers/store/derivedWithUnsubscribe.ts
deleted file mode 100644
index a02619c6..00000000
--- a/src/lib/internal/helpers/store/derivedWithUnsubscribe.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { derived, type Readable, type Stores, type StoresValues } from 'svelte/store';
-import { safeOnDestroy } from '../lifecycle';
-
-/**
- * A utility function that creates a derived store that automatically
- * unsubscribes from its dependencies.
- *
- * @template S - The type of the stores object
- * @template T - The type of the derived store
- * @param stores - The stores object to derive from
- * @param fn - The function to derive the store from
- * @returns A derived store that automatically unsubscribes from its dependencies
- */
-export function derivedWithUnsubscribe<S extends Stores, T>(
-	stores: S,
-	fn: (values: StoresValues<S>, onUnsubscribe: (cb: () => void) => void) => T
-): Readable<T> {
-	let unsubscribers: (() => void)[] = [];
-	const onUnsubscribe = (cb: () => void) => {
-		unsubscribers.push(cb);
-	};
-
-	const unsubscribe = () => {
-		// Call all of the unsubscribe functions from the previous run of the function
-		unsubscribers.forEach((fn) => fn());
-		// Clear the list of unsubscribe functions
-		unsubscribers = [];
-	};
-
-	const derivedStore = derived(stores, ($storeValues) => {
-		unsubscribe();
-		return fn($storeValues, onUnsubscribe);
-	});
-
-	safeOnDestroy(unsubscribe);
-
-	const subscribe: typeof derivedStore.subscribe = (...args) => {
-		const unsub = derivedStore.subscribe(...args);
-		return () => {
-			unsub();
-			unsubscribe();
-		};
-	};
-
-	return {
-		...derivedStore,
-		subscribe,
-	};
-}
diff --git a/src/lib/internal/helpers/store/effect.ts b/src/lib/internal/helpers/store/effect.ts
index 962c7983..29ba1ff4 100644
--- a/src/lib/internal/helpers/store/effect.ts
+++ b/src/lib/internal/helpers/store/effect.ts
@@ -1,6 +1,6 @@
-import type { Stores, StoresValues } from 'svelte/store';
+import { derived, type Stores, type StoresValues } from 'svelte/store';
 import { safeOnDestroy } from '../lifecycle';
-import { derivedWithUnsubscribe } from './derivedWithUnsubscribe';
+import { noop } from '..';
 
 /**
  * A utility function that creates an effect from a set of stores and a function.
@@ -15,19 +15,18 @@ export function effect<S extends Stores>(
 	stores: S,
 	fn: (values: StoresValues<S>) => (() => void) | void
 ): () => void {
+	let cb: (() => void) | void = undefined;
+
 	// Create a derived store that contains the stores object and an onUnsubscribe function
-	const unsub = derivedWithUnsubscribe(stores, (stores, onUnsubscribe) => {
-		return {
-			stores,
-			onUnsubscribe,
-		};
-	}).subscribe(({ stores, onUnsubscribe }) => {
-		const returned = fn(stores);
-		// If the function returns a cleanup function, call it when the effect is unsubscribed
-		if (returned) {
-			onUnsubscribe(returned);
-		}
-	});
+	const destroy = derived(stores, (stores) => {
+		cb?.();
+		cb = fn(stores);
+	}).subscribe(noop);
+
+	const unsub = () => {
+		destroy();
+		cb?.();
+	};
 
 	// Automatically unsubscribe the effect when the component is destroyed
 	safeOnDestroy(unsub);
diff --git a/src/lib/internal/helpers/store/index.ts b/src/lib/internal/helpers/store/index.ts
index 41e103de..a19c6a83 100644
--- a/src/lib/internal/helpers/store/index.ts
+++ b/src/lib/internal/helpers/store/index.ts
@@ -1,6 +1,5 @@
 export * from './derivedFromObject.js';
 export * from './derivedVisible.js';
-export * from './derivedWithUnsubscribe.js';
 export * from './effect.js';
 export * from './lightable.js';
 export * from './debounceable.js';
diff --git a/src/lib/internal/helpers/typeahead.ts b/src/lib/internal/helpers/typeahead.ts
index 6d4783e9..0ecb0df1 100644
--- a/src/lib/internal/helpers/typeahead.ts
+++ b/src/lib/internal/helpers/typeahead.ts
@@ -1,8 +1,9 @@
-import { get, writable, type Writable } from 'svelte/store';
+import { get, writable } from 'svelte/store';
+import { wrapArray } from './array.js';
 import { debounce } from './debounce.js';
-import { handleRovingFocus } from './rovingFocus.js';
 import { isHTMLElement } from './is.js';
-import { wrapArray } from './array.js';
+import { handleRovingFocus } from './rovingFocus.js';
+import { withGet } from './withGet.js';
 
 export type TypeaheadArgs = {
 	/**
@@ -45,7 +46,7 @@ const defaults = {
 
 export function createTypeaheadSearch(args: TypeaheadArgs = {}) {
 	const withDefaults = { ...defaults, ...args };
-	const typed: Writable<string[]> = writable([]);
+	const typed = withGet(writable<string[]>([]));
 
 	const resetTyped = debounce(() => {
 		typed.update(() => []);
diff --git a/src/lib/internal/helpers/withGet.ts b/src/lib/internal/helpers/withGet.ts
index ad317390..c77031b0 100644
--- a/src/lib/internal/helpers/withGet.ts
+++ b/src/lib/internal/helpers/withGet.ts
@@ -1,33 +1,96 @@
-import { get, type Writable } from 'svelte/store';
+import { get, writable, type Readable, type StoresValues, type Writable } from 'svelte/store';
 
-type WritableValue<T> = T extends Writable<infer V> ? V : never;
+type ReadableValue<T> = T extends Readable<infer V> ? V : never;
 
-export type WithGet<T extends Writable<unknown>> = T & {
-	get: () => WritableValue<T>;
+export type WithGet<T extends Readable<unknown>> = T & {
+	get: () => ReadableValue<T>;
+	destroy?: () => void;
 };
 
-export function withGet<T extends Writable<unknown>>(store: T): WithGet<T> {
-	let value = get(store);
+/**
+ * Transforms an existing store into a store with a `get` method.
+ * Uses subscriptions to keep the value up to date, so make sure to call `destroy` when you're done with it.
+ * @date 20/01/2024 - 16:38:39
+ *
+ * @export
+ * @template {Readable<unknown>} T
+ * @param {T} store
+ * @returns {WithGet<T>}
+ */
+export function withGet<T extends Readable<unknown>>(store: T): WithGet<T> {
+	return {
+		...store,
+		get: () => get(store) as ReadableValue<T>,
+	};
+}
 
-	const update: (typeof store)['update'] = (cb) => {
-		store.update((v) => {
-			const nv = cb(v);
-			value = nv;
-			return nv;
-		});
+withGet.writable = function <T>(initial: T): WithGet<Writable<T>> {
+	const internal = writable(initial);
+	let value = initial;
+
+	return {
+		subscribe: internal.subscribe,
+		set(newValue) {
+			internal.set(newValue);
+			value = newValue;
+		},
+		update(updater) {
+			const newValue = updater(value);
+			internal.set(newValue);
+			value = newValue;
+		},
+		get() {
+			return value;
+		},
+	};
+};
+
+withGet.derived = function <
+	S extends
+		| WithGet<Readable<unknown>>
+		| [WithGet<Readable<unknown>>, ...Array<WithGet<Readable<unknown>>>]
+		| Array<WithGet<Readable<unknown>>>,
+	T
+>(stores: S, fn: (values: StoresValues<S>) => T): WithGet<Readable<T>> {
+	const subscribers: Map<(value: T) => void, Array<() => void>> = new Map();
+
+	const get = () => {
+		const values = Array.isArray(stores) ? stores.map((store) => store.get()) : stores.get();
+
+		return fn(values as StoresValues<S>);
 	};
 
-	const set: (typeof store)['set'] = (v) => {
-		update(() => v);
+	const subscribe = (subscriber: (value: T) => void) => {
+		const unsubscribers: Array<() => void> = [];
+		const storesArr = Array.isArray(stores) ? stores : [stores];
+		storesArr.forEach((store) => {
+			unsubscribers.push(
+				store.subscribe(() => {
+					subscriber(get());
+				})
+			);
+		});
+
+		subscriber(get());
+
+		subscribers.set(subscriber, unsubscribers);
+
+		return () => {
+			const unsubscribers = subscribers.get(subscriber);
+			if (unsubscribers) {
+				for (const unsubscribe of unsubscribers) {
+					unsubscribe();
+				}
+			}
+			subscribers.delete(subscriber);
+		};
 	};
 
 	return {
-		...store,
-		get: () => value as WritableValue<T>,
-		update,
-		set,
+		get,
+		subscribe,
 	};
-}
+};
 
 export function addGetToStores<T extends Record<string, Writable<unknown>>>(stores: T) {
 	return Object.keys(stores).reduce(


Test patch:
diff --git a/src/lib/internal/helpers/tests/effect.spec.ts b/src/lib/internal/helpers/tests/effect.spec.ts
new file mode 100644
index 00000000..ae23aaea
--- /dev/null
+++ b/src/lib/internal/helpers/tests/effect.spec.ts
@@ -0,0 +1,54 @@
+import { writable } from 'svelte/store';
+import { effect } from '..';
+
+describe('effect', () => {
+	it('Gets called initially', () => {
+		let calls = 0;
+		const unsub = effect([], () => {
+			calls++;
+		});
+
+		expect(calls).toBe(1);
+		unsub();
+	});
+
+	it('Gets called when a store changes', async () => {
+		const w = writable(1);
+		let calls = 0;
+		const unsub = effect(w, () => {
+			calls++;
+		});
+		expect(calls).toBe(1);
+
+		w.set(2);
+		expect(calls).toBe(2);
+		unsub();
+	});
+
+	it('Returned callback gets called before new execution', async () => {
+		const w = writable(1);
+		let calls = 0;
+		const unsub = effect(w, () => {
+			return () => {
+				calls++;
+			};
+		});
+
+		w.set(2);
+		expect(calls).toBe(1);
+		unsub();
+	});
+
+	it('Returned callback gets called when unsubscribed', async () => {
+		const w = writable(1);
+		let calls = 0;
+		const unsub = effect(w, () => {
+			return () => {
+				calls++;
+			};
+		});
+
+		unsub();
+		expect(calls).toBe(1);
+	});
+});
diff --git a/src/lib/internal/helpers/tests/overridable.spec.ts b/src/lib/internal/helpers/tests/overridable.spec.ts
new file mode 100644
index 00000000..8283affc
--- /dev/null
+++ b/src/lib/internal/helpers/tests/overridable.spec.ts
@@ -0,0 +1,51 @@
+import { writable } from 'svelte/store';
+import { overridable } from '..';
+
+describe('overridable', () => {
+	it('works as expected without setting onChange fn', () => {
+		const store = writable(1);
+		const o = overridable(store);
+		expect(o.get()).toBe(1);
+
+		o.set(2);
+		expect(o.get()).toBe(2);
+	});
+
+	it('updates when original store updates', () => {
+		const store = writable(1);
+		const o = overridable(store);
+		expect(o.get()).toBe(1);
+
+		store.set(2);
+		expect(o.get()).toBe(2);
+	});
+
+	it('onChange is called when original store updates', () => {
+		const store = writable(1);
+		let called = false;
+		const o = overridable(store, ({ next }) => {
+			called = true;
+			return next + 1;
+		});
+		expect(o.get()).toBe(1);
+
+		o.set(2);
+		expect(o.get()).toBe(3);
+		expect(called).toBe(true);
+	});
+
+	it('curr and next are passed to onChange', () => {
+		const store = writable(1);
+		let curr: number | undefined;
+		let next: number | undefined;
+		const o = overridable(store, ({ curr: _curr, next: _next }) => {
+			curr = _curr;
+			next = _next;
+			return _next;
+		});
+
+		o.set(2);
+		expect(curr).toBe(1);
+		expect(next).toBe(2);
+	});
+});
diff --git a/src/lib/internal/helpers/tests/withGet.spec.ts b/src/lib/internal/helpers/tests/withGet.spec.ts
new file mode 100644
index 00000000..261052f0
--- /dev/null
+++ b/src/lib/internal/helpers/tests/withGet.spec.ts
@@ -0,0 +1,54 @@
+import { derived, readable, writable } from 'svelte/store';
+import { withGet } from '..';
+
+describe('withGet', () => {
+	it('properly gets the value of a readable store', () => {
+		expect(withGet(readable(1)).get()).toBe(1);
+	});
+
+	it('properly gets the value of a writable store', () => {
+		const { get, set } = withGet(writable(1));
+		expect(get()).toBe(1);
+
+		set(2);
+		expect(get()).toBe(2);
+	});
+
+	it('When updating the original store, withGet has the latest value', () => {
+		const original = writable(1);
+		const { get } = withGet(original);
+		expect(get()).toBe(1);
+
+		original.set(2);
+		expect(get()).toBe(2);
+	});
+
+	it('properly gets the value of a derived store', async () => {
+		const w = writable(1);
+		const d = derived(w, ($w) => $w + 1);
+
+		const { get } = withGet(d);
+		expect(get()).toBe(2);
+
+		w.set(2);
+		expect(get()).toBe(3);
+	});
+
+	it('withGet.writable', async () => {
+		const { get, set } = withGet.writable(1);
+		expect(get()).toBe(1);
+
+		set(2);
+		expect(get()).toBe(2);
+	});
+
+	it('withGet.derived', async () => {
+		const w = withGet.writable(1);
+		const d = withGet.derived(w, ($w) => $w + 1);
+
+		expect(d.get()).toBe(2);
+
+		w.set(2);
+		expect(d.get()).toBe(3);
+	});
+});
diff --git a/src/tests/range-calendar/RangeCalendar.spec.ts b/src/tests/range-calendar/RangeCalendar.spec.ts
index 493ef4f0..4c86a497 100644
--- a/src/tests/range-calendar/RangeCalendar.spec.ts
+++ b/src/tests/range-calendar/RangeCalendar.spec.ts
@@ -1,13 +1,13 @@
-import { testKbd as kbd } from '../utils.js';
+import type { CreateRangeCalendarProps, DateRange } from '$lib';
+import { CalendarDate, CalendarDateTime, toZoned, type DateValue } from '@internationalized/date';
 import { render } from '@testing-library/svelte';
 import userEvent from '@testing-library/user-event';
 import { axe } from 'jest-axe';
+import { tick } from 'svelte';
+import { writable } from 'svelte/store';
 import { describe } from 'vitest';
+import { testKbd as kbd } from '../utils.js';
 import RangeCalendarTest from './RangeCalendarTest.svelte';
-import { CalendarDate, CalendarDateTime, toZoned, type DateValue } from '@internationalized/date';
-import { writable } from 'svelte/store';
-import { tick } from 'svelte';
-import type { CreateRangeCalendarProps, DateRange } from '$lib';
 
 const calendarDateRange = {
 	start: new CalendarDate(1980, 1, 20),
@@ -292,6 +292,7 @@ describe('Range Calendar', () => {
 		valueStore.set(calendarDateRange);
 
 		await tick();
+
 		expect(startValue).toHaveTextContent('1980-01-20');
 		expect(endValue).toHaveTextContent('1980-01-25');
 		valueStore.set({