# Neodrag keeps one dragging contract across Svelte, React, Vue, Solid and plain JavaScript

> A pnpm monorepo of five framework wrappers around a shared drag core, released through changesets, with a Lit package still sitting unchecked on the roadmap.

**PuruVJ/neodrag** — One Draggable to rule them all 💍

- Repository: https://github.com/PuruVJ/neodrag
- Website: https://neodrag.dev
- Stars: 2,453 · Forks: 65
- Language: TypeScript
- License: MIT
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/puruvj-neodrag

## Five shipped wrappers and a sixth still marked as a checkbox

The README opens with the promise that defines this project: choose your framework and the dragging API behaviour will stay the same. What follows is a list of five packages, `@neodrag/svelte`, `@neodrag/react`, `@neodrag/vue`, `@neodrag/solid` and `@neodrag/vanilla`, each linked to its own README inside the `packages/` directory of a monorepo.

The roadmap section repeats that same five with checkboxes ticked, then adds one line without a tick: `@neodrag/lit`. That unchecked entry is the clearest statement of direction in the README. It also matters practically, because Lit components are the usual reason someone would reach for the Vanilla wrapper in the first place, so a planned Lit package changes how you should think about the vanilla entry point: it is a fallback with different ergonomics, not the beginning of a Lit story.

GitHub reports the repository topics as draggable, javascript, svelte and typescript. Read those as the topics the maintainer chose rather than as the package list, since the package list is longer and includes React, Vue and Solid.

The licensing is MIT and the documentation lives at neodrag.dev, with the README linking that site as its getting started link. The version numbers to know come from the npm badges rather than from the README text.

## The root manifest is a private workspace, not the published version

The repository root holds a `package.json` that is marked private, and its version field reads `1.0.1`. That number is not what you install, and reading it as such is the fastest way to be confused about where neodrag is in its own release cycle. The root manifest is the workspace container; the published packages carry the scoped `@neodrag/` names and their own independent versions.

Here is the interesting part of that root manifest:

```json
"version": "1.0.1",
"private": true,
"type": "module",
"changeset": "changeset",
"ci:version": "changeset version",
"ci:release": "changeset publish",
"sizes": "tsx scripts/gather-sizes.ts"
```

The presence of the private flag alongside `type` of module tells you the repo is an ES module workspace, and the three changeset scripts tell you the entire release path: contributors describe a change, the version command bumps the affected packages, the publish command pushes them. There is no hand-edited version bump anywhere in that list.

The rest of the manifest is a dev dependency set that spans all the wrappers at once, which is what a monorepo needs in order to test every package in one install: React and React DOM, Vue, Svelte 4, Solid, plus Vite, Vitest, jsdom and the testing library packages for both React and Svelte. Two of those testing libraries are not the whole story, though. There is no React testing library dependency in the list even though React 18 itself is a dev dependency, so React component tests may be running through a different path than the Svelte ones. If you plan to contribute a React change with tests, check how the existing React tests are written before assuming the same setup.

## Bundle size is a build step, not a promise in the README

One line of the root manifest deserves more attention than it gets: a `sizes` script that runs `tsx scripts/gather-sizes.ts`, paired with a `brotli-size` dependency and a `fast-glob` dependency. Together those say the project measures what each package weighs after compression, on demand, from a script, rather than quoting numbers in prose that go stale.

The `docs:build` script wires this into the documentation site. It compiles the packages, gathers sizes, then builds whatever lives in the `docs` directory. So the size figures you see on the site are produced by the same command a contributor runs, which is a healthier arrangement than hand-maintained tables.

Brotli rather than gzip is a deliberate choice worth noticing, since brotli is what a modern CDN will use when it can. It also means the numbers on the site are closer to what a user downloads over a real connection than a gzip figure would be.

The repository tree supports the picture. Alongside `packages/` and `docs/` there is a `scripts/` directory, a `pnpm-lock.yaml`, and a `pnpm-workspace.yaml` at the root. The lockfile at the repository root, rather than one per package, is the pnpm workspace pattern, and it means your install in a fork resolves the same dependency graph the maintainer resolves.

## The release archive is all prerelease, and it stopped a year ago

The published releases tell a specific story. The three most recent are `@neodrag/vue@3.0.0-next.9`, `@neodrag/vanilla@3.0.0-next.9` and `@neodrag/svelte@3.0.0-next.8`, all published on 2025-08-03 within seconds of each other. Each release body is a dependency bump and nothing else: it records that `@neodrag/core` moved to `3.0.0-next.8`, linking a single commit.

So a 3.0 line exists and it is built from a shared core package that the wrappers depend on rather than duplicate. That is the architecture the README implies when it promises identical behaviour across frameworks, made concrete in the release metadata.

Now the part that deserves attention. GitHub reports the last push to the repository on 2026-08-10, and the newest tagged release is from August 2025. A year of commits with no new release tag is not proof of anything bad, but it does mean the prerelease channel has been sitting for roughly twelve months while the repository itself kept moving. If you are evaluating this library, that gap is a practical question rather than a rhetorical one: ask whether a stable 3.0 is planned, and until you have an answer, pin an exact prerelease version or an exact stable version rather than a range.

GitHub also reports 2,452 stars, 65 forks and 79 open issues. An open issue count near the fork count is typical of a project with one main maintainer and a steady contributor list, and the README credits seven contributors by name with an all-contributors table.

## Reading the per framework READMEs instead of the root one

The root README is deliberately short. It names the packages, links the docs site, shows a contributors table, and stops. Everything that would matter for actually using the library lives in the package level READMEs under `packages/svelte`, `packages/react`, `packages/vue`, `packages/solid` and `packages/vanilla`.

That split has a practical consequence: the same conceptual feature may be spelled differently in each wrapper because each framework has its own idiom for reactivity and lifecycle. Svelte users will find a Svelte-shaped entry point, Vue users a directive or component binding, React users a hook or ref pattern. The consistency claim in the README is about dragging behaviour, not about API surface, and the difference matters if you are porting an implementation between wrappers.

The docs site is the intended place to compare them, and it is also where the size numbers come from, so the site is doing double duty as reference and benchmark.

One small cosmetic detail that suggests the README has been edited more than once: the npm badge for `@neodrag/vanilla` is passed a colour value of `fff`, which is white, so that badge renders effectively invisible on a light background while the Svelte, Vue, React and Solid badges all get real colours. It is a trivial detail, but it is the kind of thing that tells you the badge row was assembled at different times rather than generated from a template.

## What the repository layout implies about contributing

The tree is short enough to read in one pass: `.changeset/`, `.github/`, `.gitignore`, `.prettierrc`, `.vscode/`, `LICENSE.txt`, `README.md`, `docs/`, `package.json`, `packages/`, `pnpm-lock.yaml`, `pnpm-workspace.yaml` and `scripts/`.

Three of those entries carry most of the signal about how work gets done here. The `.changeset/` directory is the visible counterpart of the release scripts in the manifest, and its presence means a contributor does not edit a version number in a package file. The `.prettierrc` means formatting is not a review argument. The `.vscode/` directory suggests the maintainer's editor settings are committed so contributors get the same behaviour without configuring anything.

The README states that contributions of any kind are welcome and that the project follows the all-contributors specification. Combined with the layout, the practical reading is that a change which touches one wrapper, adds a changeset entry, and updates that wrapper's README is a complete contribution.

What the layout does not tell you is where cross-wrapper consistency is enforced. There is no top-level test directory outside the packages, so if there is a test asserting that all five wrappers behave identically, it lives inside one of them or in continuous integration you cannot see from the tree. That is worth asking about before you rely on the consistency promise in a project where two wrappers ship.

## Conclusion

Neodrag is worth reaching for when your product needs dragging in more than one framework and you would rather not maintain two implementations, because the pitch is that the API behaviour stays the same whichever wrapper you install. The wrapper packages are thin, the releases are driven by changesets, and the docs site tracks bundle size as a build step rather than a footnote. The thing to check before you commit is release channel: the tagged releases in the archive are all 3.0.0-next prereleases published in August 2025, while the last push to the repository is reported on 2026-08-10, so the prerelease line has not shipped a stable 3.0 for about a year and the tree carries both pnpm and a dedicated size-gathering script. Pin an exact version rather than a caret, read the options table for the wrapper you actually install, and treat neodrag.dev as the place where the per framework README lives.

## FAQ

### What is the best drag and drop library for React?

That depends on what you need dragged. For a drag handle on a modal or a sortable-looking list where the library only moves pixels and you commit the order yourself, `@neodrag/react` is a reasonable candidate, since it exposes the same dragging behaviour as the Svelte, Vue, Solid and vanilla packages. If you need reordering semantics, keyboard accessibility, or automatic data movement, you want a library built around a data model instead of around pointer events, and you should check accessibility support before anything else.

### Which frameworks does Neodrag support?

The README lists five packages: `@neodrag/svelte`, `@neodrag/react`, `@neodrag/vue`, `@neodrag/solid` and `@neodrag/vanilla`. The roadmap also lists `@neodrag/lit` as not yet done. Each framework has its own README under `packages/` in the repository.

### How does Neodrag release new versions?

Through changesets. The root package.json defines a `changeset` script for describing a change, `ci:version` to run `changeset version`, and `ci:release` to run `changeset publish`. The `.changeset/` directory in the tree is where those change descriptions live. Contributors do not hand-edit version numbers.

### Is Neodrag's 3.0 release finished?

The tagged releases in the archive are all 3.0.0-next prereleases, the most recent published on 2025-08-03. GitHub reports the last push on 2026-08-10. So the repository has kept moving while the 3.0 prerelease line has not shipped a stable tag for about a year. Pin an exact version rather than a range if you depend on it.

## Sources

- [License: MIT](https://github.com/PuruVJ/neodrag/blob/main/LICENSE)
- [Project website](https://neodrag.dev)
- [PuruVJ/neodrag on GitHub](https://github.com/PuruVJ/neodrag)
- [README](https://github.com/PuruVJ/neodrag/blob/main/README.md)
- [Releases](https://github.com/PuruVJ/neodrag/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/puruvj-neodrag
