Skip to content

feat(cli): sv create --from-playground #662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

manuel3108
Copy link
Member

@manuel3108 manuel3108 commented Aug 3, 2025

Closes #602

You can now run pnpx https://pkg.pr.new/sveltejs/cli/sv@662 create --from-playground=https://svelte.dev/playground/hello-world. This is currently doing more or less the same the stuff the Download App button in the playground is doing. Apart from that, you can choose additional addons, ts vs js and install deps. External dependencies are auto-detected and installed into the package.json

Todos:

  • more (manual) testing
  • consider if we should prompt the user before installing external dependencies on the local computer
  • handle svelte-?version= parameter from the playground url
  • Feedback from dominikg: one thing to remember is that this is untrusted input basically, the playground could reference malicious packages, so installation with --ignore-scripts and making users aware that they have to check the content beforehand would be good.

Copy link

changeset-bot bot commented Aug 3, 2025

🦋 Changeset detected

Latest commit: 188c9e5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
sv Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

pkg-pr-new bot commented Aug 3, 2025

Open in StackBlitz

npx https://pkg.pr.new/sveltejs/cli/sv@662
npx https://pkg.pr.new/sveltejs/cli/svelte-migrate@662

commit: 188c9e5

@svelte-docs-bot
Copy link

@jycouet
Copy link
Contributor

jycouet commented Aug 3, 2025

This is exciting 🤩

I have this one that could show a few things: https://svelte.dev/playground/770bbef086034b9f8e337bab57efe8d8

  • App.svelte => /src/routes/+page.svelte
  • Footer.svelte => /src/routes/Footer.svelte easy like this, all imports are still working.
  • import * as changeCase from "change-case"; => Need to add this in package.json
  • Maybe the main layout can be tuned to have a "Playground" style with a link to the playground.
localhost_5174_
+layout.svelte example
<script lang="ts">
	import favicon from '$lib/assets/favicon.svg';
let { children } = $props();
</script>

svelte:head

</svelte:head>

Svelte

Playground

<main class="content">
	{@render children?.()}
</main>
<style> :global(body) { margin: 0; } .layout { min-height: 100vh; background-color: #1c1e22; } .navbar { display: flex; justify-content: space-between; align-items: center; padding: 1rem 2rem; background-color: #23272f; border-bottom: 1px solid #2d3139; } .nav-left { display: flex; align-items: center; gap: 1rem; } .svelte-icon { display: flex; align-items: center; text-decoration: none; transition: opacity 0.2s ease; } .svelte-icon:hover { opacity: 0.8; } .title { color: #ffffff; font-size: 1.5rem; font-weight: 600; margin: 0; } .nav-right { display: flex; align-items: center; } .playground-link { color: #ffffff; text-decoration: none; font-weight: 500; padding: 0.5rem 1rem; border-radius: 0.375rem; transition: background-color 0.2s ease; } .playground-link:hover { background-color: #2d3139; } .content { padding: 2rem; color: #ffffff; } </style>

@manuel3108
Copy link
Member Author

I have this one that could show a few things: https://svelte.dev/playground/770bbef086034b9f8e337bab57efe8d8

This is perfect, and i was able to get it fully working from the tests.
The only thing remaining here is code optimization and making it work from the core cli, instead from the crete tests.

Maybe the main layout can be tuned to have a "Playground" style with a link to the playground.

Not sure, I'm a fan of this. The current "download app" button does nothing like this. Also, I'm not sure if this provides any additional value to the user, or just causes styling problems because of the added css. We can always add this later if users want this.

@jycouet
Copy link
Contributor

jycouet commented Aug 15, 2025

Great progress 🚀🚀🚀 Nice

Maybe the main layout can be tuned to have a "Playground" style with a link to the playground.

Not sure, I'm a fan of this. The current "download app" button does nothing like this. Also, I'm not sure if this provides any additional value to the user, or just causes styling problems because of the added css. We can always add this later if users want this.

The cool thing about a layout like this is that:

  • You can have a link back to the playground. so you know where it's coming from.
  • with css per component, it should not affect anything
  • you can escape from it by just deleting one file
  • we can feel that we are "home" in our playgound... locally (with similar style)

Yes, I love this idea 😜
But it can come later too with a flag in or out ;)

Anyhow, very nice job

@manuel3108
Copy link
Member Author

Updated pr description, this is working now. Let me know what you think.

Copy link
Contributor

@jycouet jycouet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The result is like this:
Image

Comments in random order:

  • I find it strange to have the "Template content" coming from a playground. Maybe +page.svelte should have ONLY <App />, nothing else ?
  • I still like the playground layout idea :p
  • Maybe a default folder name could be proposed "svelte-playground-slug-name-of-playgound" ?
  • Maybe the readme.md could mention the origin of the playground ?
  • If some extra deps are needed, prompt it in CLI and add it to readme.md ?

It's probably nitpicking, because it's working well already.
Great work 🎉🎉🎉

import * as js from '@sveltejs/cli-core/js';

export async function write_playground_files(url: string, cwd: string): Promise<void> {
if (!validatePlaygroundUrl(url)) throw new Error(`Invalid playground URL: ${url}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this will be a "common" mistake in the url formating.

Today I got:

Image

Maybe we can help more with a nice message like:
You typed: "toto", it should be a valid playground url like ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe even not exiting the cli when this happen to have the chance to paste a valid url ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exact one should only trigger when you call create programmatically. But you are absolute right, this should be fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

sv create allow download from playground
2 participants