Skip to content

Repository files navigation

Solid Primitives

Solid Primitives

pnpmturborepocombined-downloads

A project that strives to develop high-quality, community contributed Solid primitives. All utilities are well tested and continuously maintained. Every contribution to the repository is checked for quality and maintained to the highest degree of excellence. The ultimate goal is to extend Solid's primary and secondary primitives with a set of tertiary primitives.

While Solid Primitives is not officially maintained by the SolidJS Core Team, it is managed by members of the SolidJS core and ecosystem teams. This separation allows the core library to iterate independently while allowing Solid Primitives to remain in-sync with future plans.

Philosophy

The goal of Solid Primitives is to wrap client and server side functionality to provide a fully reactive API layer. Ultimately the more rooted our tertiary primitives are, the more they act as foundation within Solid's base ecosystem. With well built and re-used foundations, the smaller (aggregate tree-shaking benefits), more concise (readability) and stable (consistent and managed testing + maintenance) applications can be overall.

Primitives

NameStagePrimitivesSizeNPM

Inputs

active-elementSTAGEcreateActiveElement
createFocusSignal
SIZEVERSION
input-maskSTAGEcreateInputMaskSIZEVERSION
keyboardSTAGEuseKeyDownList
useCurrentlyHeldKey
useKeyDownSequence
createKeyHold
createShortcut
SIZEVERSION
mouseSTAGEcreateMousePosition
createPositionToElement
SIZEVERSION
pointerSTAGEcreatePointerListeners
createPerPointerListeners
createPointerPosition
createPointerList
SIZEVERSION
scrollSTAGEcreateScrollPosition
useWindowScrollPosition
SIZEVERSION
selectionSTAGEcreateSelectionSIZEVERSION

Display & Media

audioSTAGEmakeAudio
makeAudioPlayer
createAudio
SIZEVERSION
boundsSTAGEcreateElementBoundsSIZEVERSION
devicesSTAGEcreateDevices
createMicrophones
createSpeakers
createCameras
createAccelerometer
createGyroscope
SIZEVERSION
idleSTAGEcreateIdleTimerSIZEVERSION
intersection-observerSTAGEmakeIntersectionObserver
createIntersectionObserver
createViewportObserver
createVisibilityObserver
SIZEVERSION
mediaSTAGEmakeMediaQueryListener
createMediaQuery
createBreakpoints
usePrefersDark
SIZEVERSION
page-visibilitySTAGEcreatePageVisibilitySIZEVERSION
resize-observerSTAGEcreateResizeObserver
createWindowSize
createElementSize
SIZEVERSION
stylesSTAGEcreateRemSizeSIZEVERSION

Browser APIs

broadcast-channelSTAGEmakeBroadcastChannel
createBroadcastChannel
SIZEVERSION
clipboardSTAGEmakeClipboard
createClipboard
copyToClipboard
SIZEVERSION
event-listenerSTAGEcreateEventListener
createEventSignal
createEventListenerMap
WindowEventListener
DocumentEventListener
SIZEVERSION
event-propsSTAGEcreateEventPropsSIZEVERSION
fullscreenSTAGEcreateFullscreenSIZEVERSION
geolocationSTAGEcreateGeolocation
createGeolocationWatcher
SIZEVERSION
mutation-observerSTAGEcreateMutationObserverSIZEVERSION
permissionSTAGEcreatePermissionSIZEVERSION
storageSTAGEcreateStorage
createCookieStorage
createAsyncStorage
createStorageSignal
createLocalStorage
createSessionStorage
SIZEVERSION
timerSTAGEmakeTimer
createTimer
createTimeoutLoop
createPolled
createIntervalCounter
SIZEVERSION
uploadSTAGEcreateFileUploader
createDropzone
SIZEVERSION
workersSTAGEcreateWorker
createWorkerPool
createSignaledWorker
SIZEVERSION

Network

connectivitySTAGEcreateConnectivitySignalSIZEVERSION
fetchSTAGEcreateFetchSIZEVERSION
graphqlSTAGEcreateGraphQLClientSIZEVERSION
streamSTAGEcreateStream
createAmplitudeStream
createMediaPermissionRequest
createAmplitudeFromStream
createScreen
SIZEVERSION

Utilities

contextSTAGEcreateContextProviderSIZEVERSION
cursorSTAGEcreateElementCursor
createBodyCursor
SIZEVERSION
dateSTAGEcreateDate
createDateNow
createTimeDifference
createTimeDifferenceFromNow
createTimeAgo
createCountdown
createCountdownFromNow
SIZEVERSION
event-busSTAGEcreateSimpleEmitter
createEmitter
createEventBus
createEventHub
createEventStack
SIZEVERSION
event-dispatcherSTAGEcreateEventDispatcherSIZEVERSION
i18nSTAGEcreateI18nContext
useI18n
SIZEVERSION
immutableSTAGEList of functionsSIZEVERSION
mapSTAGEReactiveMap
ReactiveWeakMap
SIZEVERSION
paginationSTAGEcreatePaginationSIZEVERSION
platformSTAGEList of variablesSIZEVERSION
promiseSTAGEpromiseTimeout
raceTimeout
until
SIZEVERSION
propsSTAGEcombineProps
filterProps
SIZEVERSION
scheduledSTAGEdebounce
throttle
scheduleIdle
leading
SIZEVERSION
script-loaderSTAGEcreateScriptLoaderSIZEVERSION
setSTAGEReactiveSet
ReactiveWeakSet
SIZEVERSION
shareSTAGEcreateSocialShare
createWebShare
SIZEVERSION

Reactivity

destructureSTAGEdestructureSIZEVERSION
memoSTAGEcreateLatest
createWritableMemo
createLazyMemo
createAsyncMemo
createDebouncedMemo
createDebouncedMemoOn
createThrottledMemo
createPureReaction
createMemoCache
createReducer
SIZEVERSION
rootlessSTAGEcreateSubRoot
createCallback
createDisposable
createSharedRoot
SIZEVERSION
signal-buildersSTAGEList of buildersSIZEVERSION
triggerSTAGEcreateTrigger
createTriggerCache
createWeakTriggerCache
SIZEVERSION

Control Flow

keyedSTAGEkeyArray
Key
Entries
SIZEVERSION
rangeSTAGErepeat
mapRange
indexRange
Repeat
Range
IndexRange
SIZEVERSION
refsSTAGEmergeRefs
elements
refs
mapRemoved
Children
Refs
Ref
unmount
SIZEVERSION

Animation

rafSTAGEcreateRAF
targetFPS
SIZEVERSION
tweenSTAGEcreateTweenSIZEVERSION

Contribution Process

Solid Primitives strives to provide idiomatic Solid principles but also allow room for innovation and experimentation. In a growing community many opinions and patterns merge together to produce a de facto standard. Managing opinions and expectations can be difficult. As a result, in November 2021 Solid Primitives implemented a ratification/approval tracking process roughly modelled on TC39 Proposal Stage Process. The following summarizes these stages briefly:

StageDescription
XDeprecated or rejected
0Initial submission
1Demonstrations and examples
2General use (experimental)
3Pre-shipping (final effort)
4Accepted/shipped

Any primitive Stage 0-1 should be used with caution and with the understanding that the design or implementation may change. Beyond Stage 2 we make an effort to mitigate changes. If a primitive reaches Stage 2 it's likely to remain an official package with additional approvement until fully accepted and shipped.

Design Maxims

Other frameworks have large and extremely well established ecosystems. Notably React which has a vast array of component and hooks. The amount of choice within the ecosystem is great but often these tools are built as one-offs resulting in often un-tested logic or are designed with narrow needs. Over time the less concise these building blocks are the more they tend to repeat themselves. Our goal with Primitives is to bring the community together to contribute, evolve and utilize a powerful centralize primitive foundation.

All our primitives are meant to be consistent and sustain a level of quality. We guarantee that each is created with the utmost care. Our primitives are:

  1. Documented and follow a consistent style guide
  2. Be well tested
  3. Small, concise and practical as possible
  4. A single primitive for a single purpose
  5. No dependencies or as few as possible
  6. SSR safe entries (or short-circuits where needed) provided
  7. Wrap base level Browser APIs
  8. Should be progressively improved for future features
  9. Be focused on composition vs. isolation of logic
  10. Community voice and needs guide road map and planning
  11. Strong TypeScript support
  12. Support for both CJS and ESM
  13. Solid performance!

Basic and Compound Primitives

Each primitive is designed with composition in mind. A major rule in designing our primitives is deciding that the interface of primitives should be composable or segmented. For this reason every API is intricately studied and considered to be composed (stacked with features) or decomposed into smaller units. Designing our primitives in this manner allows for better tree-shaking and extendable complexity only as needed. You should only ship what you have to by picking from existing primitives as your foundational building blocks.

Much of the design decisions in naming are best described in the 7 Lessons to Outlive React talk by swyx. We strive to follow a similar design pattern promoted by the React core team.

make (non-reactive) vs create (reactive)

Solid uses the create prefix to define a primitive that provides reactive utility. Solid Primitives reinforces this pattern but in an effort to enhance composability we have also introduced the make prefix for identifying non-reactive foundation primitives. Having a non-reactive alternative means that the primitive does the bare essentials such as cleaning up events or interupting a process. ie. makeTimer will create and clean-up the scheduler, providing only a clear method. createTimer provides a properly reactive primitive that composes it.

Managing Primitive Complexity

Solid Primitives is mostly about supplying 80-90% of the common-use cases for the end-user. We prefer to be less prescriptive than other hook libraries such as VueUse and supply granular solutions as opposed to monolithic primitives. The remaining 10-20% of complex use cases are likely not to be covered with this library. This is on purpose to limit the potential of bloat and extended complexity. This project strives to provide foundations and not cumulative solutions. We expect the broader ecosystem will fill the remaining need as further composition to this projects effort. This allows for just the right amount of prescription and opinion.

NPM Release and Repository Structure

Solid Primitives is a large and growing project and the way we manage and release updates has been setup to suit the projects scope. The approach we've taken with organizing our packages and npm releases is more granular than other projects such as VueUse which ship all updates in a single release.

There are a number of benefits to this including small download sizes, reducing bloat and not shipping experimental/unnecessary primitives that users don't need or want locally. This does mean a bit more effort to install precisely what you need. As a team we've decided that this tradeoff is beneficial and valuable.

CLI Helpers

Available node scripts for managing packages and creating new ones:

  • pnpm run update-readme - This will update the list of primitives by inspecting individual packages.
  • pnpm run new-package name-of-your-package - A helper to setup a primitive template package.
  • pnpm run changeset - This will create a changeset file for updated packages.

Planned Primitives

Display & Media

  • createDragAndDrop

Device

  • createBattery

Browser

Network

  • createNotification
  • createPush
  • createConnectionObserver

Inputs

  • createGesture (in progress)
  • createCompositionObserver (CompositionEvent observer)
  • createForm
  • createInput
  • createTouch

Utilities

About

A library of high-quality primitives that extend SolidJS reactivity.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages