Our Github is: https://github.com/pynecone-io/pynecone
Python is one of the most popular programming languages in the world. Webdev is one of the most popular applications of programming. So why can’t we make full-stack web apps using just Python?
We worked in the AI/infra space and saw that even skilled engineers who wanted to make web apps but didn’t know traditional frontend tools like Javascript or React found it overwhelming and time consuming to learn. On the other hand, no code and low code solutions that save time in the development process lack the flexibility and robustness of traditional web development. These tools are great for prototyping, but they can be limiting as your app becomes more complex. We wanted to build a framework that is easy to get started with, yet flexible and powerful enough so you don’t outgrow it. Our main website is fully built with Pynecone and deployed on our hosting service.
In Pynecone, the frontend compiles down to a React/NextJS app, so from the end-user’s perspective it looks like any other website. We have 60+ built-in components ranging from forms to graphing. Components are defined as Python functions. They can be nested within each other for flexible layouts, and you can use keyword args to style them with full CSS. We also provide a way to easily wrap any existing React component. Our goal is to leverage the existing webdev ecosystem and make it accessible to Python devs.
The app state is just a class. State updates are functions in the class. And the UI is a reflection of the state. When the user opens the app, they are given a unique token and a new instance of the state. We store user state on the backend, and use Websockets to send events and state updates. When a user performs an action, such as clicking a button, an event is sent to the server with the client token and the function to handle the event. On the server side, we retrieve the user's state, execute the function to update the state, then send the updated state back to the frontend for rendering. Since Pynecone is 100% Python, you can easily integrate all your existing Python libraries into your app. In the future, we hope to leverage WebAssembly to offload many operations to the client.
Once your app is built, the next big challenge is deploying it. We’re building a single-line deploy, so you can type pc deploy and get a URL of your live app in minutes. Since we specialize in hosting a single type of app, we aim to provide a zero configuration deployment process. We are still working on releasing the hosting service, but you can sign up for its waitlist on our homepage. Alternatively, you can choose to host your app with your preferred cloud provider.
Things users have built with Pynecone so far include internal apps ranging from CRM to ML tools, UIs for LLM apps, landing pages, and personal websites. If you use Python, we would love to hear your thoughts and feedback in the comments!
My only question is why it took so long for someone to implement it? And where are the equivalent libraries for Go, Rust and Java?
https://github.com/plotly/dash https://docs.bokeh.org/en/latest/
I tried using it a little bit but the reality is if you need JS to make your app more interactable it's really worth it to just learn some JS. As soon as you need something complex the extra layer of abstraction just gets in the way and becomes more of a headache, and if you don't need anything complex then you don't need a fancy JS solution in the first place.
JS only becomes complex when you are trying to create an enterprise version of your app along with a build platform. You can always just sprinkle in <script> tags in your HTML for simple one liners without getting into the weeds.
You can be a lot more productive if you avoid JS entirely.
If it's going to be rendered by and live in a web browser it will either be complicated or limited in some way (like low code/no code tools).
Not aware of anything yet for Go/Rust, but Java and Python have had libs like this for a while now (to the point that Pyjamas hasn't been updated in a decade):
* GWT (Java)
* Pyjamas (Python)
* Vaadin (Java)
Those are general purpose. After that you have the sci/data-oriented python frameworks like dash, streamlit, etc.
Most of the problems in web front have been solved in JS (think CSS styles, state management) re-writting it in python would be pain, especially when everything compiles to js
Hence the whole debate about signals vs no signals last week. :)
Uhhhh. Because it didn’t. Google GWT was huge on the hype cycle about 15 years ago.
You know this has been done before over a decade ago, multiple times in Java and Python.
Not saying the space can’t be improved upon but I fail to see how it’s any more revolutionary now.
Compile-to-JS approach started to appear in mid 2000s.
This is by far the first front-end python implementation/framework. Skulpt, Brython, Anvil, PyFyre, PyScript, PyWebIO, and the list goes on…
So I get the point of the project, I can see a mathematicians getting value out of this.
Still, I would advice against using this for anything else than a small project (in the current state):
- any action your perform means a round trip to the server. This is why the counter seems so slow. Everytime you click on increment, it goes through the entire internet, ask for +1, and get the answer, then update the page.
- easy things will be easy, but even the average things are going to be hard. Every time you will want something that is not provided out of the box, the workaround is going to be painful.
- you are coding with react, one of the most complicated framework there is, but with a layer of indirection turning it into a black box. You better hope everything goes well because I don't wish debugging that on anyone.
- the database layer is going to bite you if you start to get fancy. Guaranteed.
- if you need this, you probably can't assess security. So no way to know if your website is secured. In fact, you can pretty much bet it is not.
This means if you use it for something big, you will eventually hit some kind of a big wall. Or something kind of painful experience that will possibly harm the project.
But of course, if the alternative is to never having started the project in the first place, you should definitely go for it.
The deployment being a pain for most python dev, this alone will make your life way easier, and 99% of projects don't have more that a few requests per minutes and a couple of pages anyway.
Just know what you get into: this is a trade off, as everything in engineering, not a unicorn.
Also, this is the Y combinator, so I assume there is a bigger plan behind this.
Good luck to the creators though, anything that move the needle even is good to attempt.
> any action your perform means a round trip to the server. This is why the counter seems so slow. Everytime you click on increment, it goes through the entire internet, ask for +1, and get the answer, then update the page.
Seems inconsistent with OP's
> the frontend compiles down to a React/NextJS app, so from the end-user’s perspective it looks like any other website
The python functions are NOT executed on the frontend.
But yes, it is a tradeoff and the abstractions underneath are leaky. It is not just React but NextJS and then the whole NodeJS ecosystem which is surely one of the most challenging ones.
That client/web part could have been tackled by writing a micro library in pure JS with no transpilers of any sort - and probably they might do it in future not sure how, but something like Brython[0] could be interesting.
Meaning your server-side app is not stateless? Is there an instance for every client?
Back in early 2000s, i used to be more of a front-end dev...but over the years of being more of a manager (or PM or product manager) i stepped away from daily development...So, you know, I lost my touch. But a few years ago when i tried to dip back into things again, i got turned off from needing to "learn all the JS stuff". It feels all so bloated and so much work for what to me seems minimal gain. Nowadays, i much prefer back-end development (not that iots easy, but maybe it just clicks more for me without so much JS stuff)...so when i see frameworks like this one, i get more interested.
Long time ago -for a personal project- I used CherryPy, which is simpler and easy to learn. I don't know where it stands today, but it's another option.
Is there a roadmap? I see the GitHub project board is pretty focused on v0.1.20. I am curious what are your plans for client side code via wasm? I feel like that is a critical missing piece for me.
* Web with python : yes, make sense, python is very friendly it's kind of the closest to no-code we can do
* No benchmark : ouch, no way I am touching this without knowing, at least in the big picture, what to expect
* Front-end : so this is a wrapper of Chackra UI which is itself a wrapper of React (which is the slowest framework out there) -> not really what I am looking for. I can understand that for some quickly made website this can be OK. For a serious dev I don't think this will have much appeal. I guess you need to target casual users.
* Not much bloat on the dependencies so this is quiet good on that front, I was expecting way worse.
* Your a startup and backed by YC and I see no business plan, priced service nor anything alike This is very suspect, for me as long as I don't understand how you are meant to work in the long run I will not involved myself using your library.
I am probably not your target user, I will stick with flask/tornado for prototyping my back-end and use lesser known but amazingly light and fast front-end framework. Good luck going forward.
My personal favorite is Svelte
Using Android and Samsung internet.
Edit: I took a video screenshot https://voicer.com/v/HSpS9
Edit: Seeing the comment about websockets and server location, I am in the EU so it's possibly that. I don't get why state of the frontend is stored on the backend though. Seems an obvious performance issue.
Also, I turned off WiFi and then clicked the counter a couple times. Obviously the clicks didn't render. When I turned it on, then the counter updated one at a time at what felt like 300ms intervals. I often use the web from the train as I commute and data service can be spotty. I expect I'd see input latency in the minutes if I tried.
I think this is only viable if you're certain all your users have ping <100ms, and are on stable connections.
If you have to use this model, try batching user events (10 clicks => increment by 10) and cancelling old events (slider events at 5, 10, 20; only send slider=20 event).
We should talk. If your open source roadmap includes getting rid of your npm dependency then we might just migrate to Pynecone for our front-end.
This is immensely valuable to a lot of Python devs, especially in finance/quant community. Great work!
Edit: The reason why this is so impactful is b/c most users have no idea how to build a react app (along with the circus of build/deploy train one typically entails). They just want a quick-and-dirty UI for their Python model they developed in Jupyter or similar. If the model has legs, a separate FE dev would build a fancier front end later.
I can see all the SwiftUI[0] inspiration in how to make compositions, instead of relying on CSS only.
Recently there was Rux[1] which is JSX in Rails, but that is really only dealing with ergonomics oh having Components in a nice DSL.
Then there is actual deployment story. I recently made a DRF + Next App, and I spent too much time thinking about deployment. And yea, for the volume I need to server, having a single artifact deployed, with SSR, is wonderful.
How is the intellisense support? That's one of the best features of recent JS/TS frameworks on VSCode, and I don't use JetBrains IDEs. Are there JS/CSS escape hatches? Is the goal to focus on speed of deployment or, a Python DSL over JS libraries?
Good luck either way!
[0] https://developer.apple.com/xcode/swiftui/ [1] https://github.com/camertron/rux
Please please tell me you're aware of those two and didn't build this unaware of those options.
Background: I was commissioned by a previous employer to fork Plotly Dash and build a drag and drop BI tool with it.
EDIT: I see that the website is generated using pynecone itself. Looks very nice - cool stuff.
I will def have to check this out and keep it on my radar. I used to work for a consulting place where we would have to spin up tons of one-off apps and this seems perfect for that.
Say for example, you have Model A on a server which has parameters X, Y and Z.
To load Model A in Dash is easy enough. To load its parameters as inputs with all those callbacks and imports becomes a bit messy. I've found react to just be better for that, at the end of the day.
> For performance reasons, you may want to trigger state change only when the user releases the slider.
Not a great workaround, now I can't see the number I'm selecting. With the 500ms render time, it's going to feel really slow to pick a value. The perf needs to be fixed for this to be usable.
https://pynecone.io/docs/state/overview outlines that is the case but leaves out the detail that it's using Socket.io.
Gather if you want to use this then and have it not suck you are going to need some form of edge compute.
But as someone who feels most at home with Python, I always love to see new competition in this space.
This looks wonderful, but the inability to self host is a killer from the solo developer point of view. Being limited to 50,000 database rows on the free account isn't ideal.
https://anvil.works/open-source
(I'm a founder)
This will be so useful for Computer Science students to easily have an app ready right after their first semester. (Or even Stats major, etc)
Often times, a webapp creation usually involves student learning JS and all the ecosystem.
Join the growing open-source community of Pynecone developers.
3000+ Projects created per month
5700+ GitHub stars
600+ Discord community members
One nit, on your landing page it has a typo, missing "framework /that/ doesn't" > Never get locked into a framework doesn't support your existing tech stack.
Also, your Gallery has highly responsive SPAs, but for some reason the counter here[1] is very slow on a cold load
I'm sorry, what?
I've just happened to run across a few of them recently as I was looking to see what else was new out there for easier ways to build quick and dirty web apps.
Question: I see that the ORM assumes a SQL backend. Do you have any plans to support key/value stores, or is it easy to change out the ORM?
I'm thinking this would be perfect for deployment into AWS Lambda for the backend, Cloudfront for the front end, and DynamoDB for the data.
I'm not seeing any one obvious candidate in the GitHub repo results if this is a popular tool.
https://github.com/search?utf8=%E2%9C%93&q=Pinecone&type=rep...
One question regarding the states: when do I get a new State allocated? Is it with every new tab? It's definitely not per-browser-session: if I open a new tab I seem to get a new state, while undoing a closed tab seems to recover its state with it though.
Also are old states gc'ed?
I am not very familiar with how modern Python wsgi servers manage states, but in Java e.g. states can be cached in the heap of the one and same JVM --- can one say that the need to use an external state store like Redis is a direct result of the underlying web server having to launch multiple Python processes in order to scale up for greater loads?
(Pretty cool, btw! Congrats on the launch)
The only different aspect is that the goal of Pynecone seems to be web apps over the network and not web interfaces to local programs.
On this page [1] when I press Decrement / Increment it feels like there's well over a second delay.
See here for bringing your own components: https://pynecone.io/docs/advanced-guide/wrapping-react
I'm curious how this compares to other efforts like this such as Streamlit? I do like the fact you compile to React/Next.js as that opens up the possibility of tapping into that rich ecosystem.
Also others have mentioned, and it might not be fair, but the name Pinecone (and variations) has sorta been taken at this point by the vector DB startup since they launched first. So I'd just bite the bullet and change this before the cost of switching rises later on.
Yeah we are looking into your other point about the name, noted.
As a react dev turned django dev, I cannot wait to get my hands on this!
Edit: how come the counter example is so slow on my iPhone 11 though ? That seems real weird https://pynecone.io/docs/getting-started/introduction
As an example, here is a macOS calculator clone in ~50 lines of Python: https://twitter.com/crunchingdata/status/1563300652918325249...
Streamlit was nice but it was built for newbie web developers - not web developers who didn't want to touch JS/TS - whereas this hits that niche quite well.
I'll certainly try to get a feel for what you built and how it differs from stuff like Streamlit. I have a love hate relationship with the latter and constantly looking for a more mature and faster moving alternative.
One reason I looked at Dreamhost for hosting is they have an unlimited # of websites tier that is super cheap(sucks because it's php). If you can't build a payment component then some kind of pay as you go option would be cool.
My only concern would be the time old problem of another level of abstraction. If the user has a problem they need to see if it is their problem, your problem, or a nextjs peoblem.
But it might be worth it for Python enthusiasts to use there language. The single file frontend/backend looks very compelling too.
I’ve played quite a bit with Streamlit, and I know lots of demo apps are built with Gradio. These two tools also aim to help build apps with only python. I remember my Streamlit app code turned into a mess when trying to manage state to support multiple user interactions.
Any comparisons with these frameworks?
Thanks
I'm a fellow founder in the Education space; would you be interested in building a series of "Tutorials" (we have to find the best shape for this) of building Pynecone apps?
That being said, what's with the bad performance? When I go to this page on Mobile: https://pynecone.io/docs/getting-started/introduction
and I press the "increment" button, it lags. It's subtle but would guess it takes over 100ms to respond.
If I mash the button repeatedly, sometimes it will actually lag so bad I can watch it continue to increment to "catch up" after I've stopped pressing.
As a professional full stack with specialization on frontend, this is not something I would find acceptable in boutique products.
But I wonder how this can be used with `asyncio`, since the handlers are pure `def` and not `async def`.
Searching the docs for `async` does return any results.
I'd suggest removing whatever checking is in place there, unless you plan to keep the gTLDs up to date.
I'm surprised you haven't mentioned anything about it in your HN comment, given it seems, at least on the face of it, extremely similar.
Are you able to go into a bit more detail about why Pynecone and not others?
Did you ever consider contributing to Streamlit instead or forking it? if so, why didn't that work out? What do you do better? Etc.
Disclaimer: I'm not too knowledgeable about this niche, however, so if I'm very off-base here then please let me know :)
I think the idea's behind the projects are a little different. Streamlit - small data science apps vs Pynecone - A more generalized framework to built a broader range of applications.
I agree with the comment about being somewhat like SwiftUI (which I like, even though I have only published one app to the App Store).
For me to be able to write a cool test app I'd need a working date picker and some kind of radio button feature (so that I could ask you to select a date and then display a list of offers on screen to select.)
I checked the docs and it seems there's a radio button, but no date picker yet.
Plus maybe the option to push a pdf result.
(My usecase: I'm a backend dev for a booking api and it would be fun to quickly build a frontend to test the API on my phone)
I think using one language for everything does have the benefit of reducing context switching.
It's about picking your comfort language for higher productivity, while making sacrifices somewhere like performance and less idiomatic.
I think I've found a bug when using f-strings:
pc.text(f'count: {State.count}'),
outputs: count: {state.count}
while... pc.text('count: ' + State.count),
outputs: count: 123
(I'm otherwise using the counter example, just with a default value of 123.)modern vanilla JS/TS isn't so bad but as a backend engineer I just cannot stay up with all the associated tooling required for building, packaging, etc. with front ends.
When it's time to put up a front end for something, my productivity craters to like 1% coding, 99% struggling with JS tooling.
* https://pinecone.io/ - Long-term Memory for AI
* https://pynecone.io/ - Frontend. Backend. Hosting. Pure Python.
Just one letter difference 'i' -> 'y'. In other context I would suspect phishing.
It seems like there's a slightly visible lag in some of the interactions (button clicks) in the docs.
>> All user state is stored on the server. Behind the scenes, events are sent as API calls to update the state on the server. The state delta is then sent to the frontend, which updates the UI to reflect the new state.
How does it scale? Your deployment example (self-hosted?) just shows you how to run what looks like a simple server. Do you just run a lot of those and throw a load balancer in between?
Any thoughts on integrating with Django, FastAPI, or Flask?
What about mobile apps?
At least the site and the example counter app seem heavily dependant on low latency. I'm overseas and it took a second or so for the hamburger menu (on mobile) to open.
Maybe pairing this with edge hosting service like fly.io would make sense.
What would have been interesting is creating blazor web assembly equivalent for python.
Let me give an example. In the Increment/Decrement we see the following Python code:
def index():
return pc.hstack(
pc.button(
"Decrement",
color_scheme="red",
border_radius="1em",
on_click=State.decrement,
),
pc.heading(State.count, font_size="2em"),
pc.button(
"Increment",
color_scheme="green",
border_radius="1em",
on_click=State.increment,
),
)
Which is supposed to build the interface for this almost-too-simple example. Note how there is a lot of custom Python code for simple HTML and CSS things that are already directly available in, well, HTML and CSS. This is how it might look like instead (pardon the inline CSS, it's just a quick comment, you can of course make this much better by writing the CSS separately): <button id="dec_btn" class="red" style="border-radius: 1em;">Decrement</button>
<h2 id="count_h" style="display: inline; font-size: 2em">0</h2>
<button id="inc_btn" class="green" style="border-radius: 1em;">Increment</button>
Then in the Python side, something like: pc.event(id='dec_btn', type='on_click', action=State.decrement)
pc.event(id='inc_btn', type='on_click', action=State.increment)
# Runs everytime the State changes (or something)
def global_update():
pc.print(id="count_h", f'{State.count}')
This way, presentation is separated from business logic, and 'everything in its right place' (c).I understand that many (most?) Python developers would like to stay away from JS, but I expect that most developers will know 80% of what is needed from basic HTML/CSS in order to do something like this. If they don't, it should be really easy to learn. I mean, come on, basic HTML/CSS is like a foundational building block of computing, and anyway, to write "HTML-in-Python" you still need to learn the basics (and then twist them into their Python doppelganger).
And I agree with you, at the beginning, it somewhat annoyed me, that this can lead to very verbose nested statements, but since I started refactoring most code into reusable components (AiO), I don't think anymore, that separated html-files would lead to a better usability. I would have a lot of small html-files. Also, I want to dynamically set the ids, so I can connect some components. Hence, I would need to use some templating engine for inserting the ids.
This works well with django, which I used for a long time, but I don't think it works with React-based apps, which are very component-driven.
I cannot give you anything Python specific, but I can share my experience with Flutter and Dart. In Flutter, you build your UI using regular Dart code and it feels great. This approach, btw, is also similar to Compose and SwiftUI (and to a lesser degree, JSX).
Here are the pros:
You don't need to switch from Java to XML, or from JavaScript to CSS/HTML, you can do everything using the same language. Instead of learning 2 or 3 languages (and their respective tools for testing, analyzing, linting, coding conventions), you can learn one well.
You need to do some semi-advanced logic on the button label or classes? No problem, just write the language you write everywhere. An IIFE solves your problem nicely? It's okay, you can just use it.
If you like working with Rx streams, or any other library, you can keep using them in your UI, no glue-libraries are needed.
Need to debug or add logging, printing, error reporting? Your toolchain already supports that.
Your IDE has terrible support for "insert templating language"? Not gonna happen here, if your IDE supports Dart (or in Pynecone's case, Python), you are good to go: you can jump to definitions, you can refactor argument names, and you can lookup usages exactly the way you are used to. You don't need to learn special syntax for conditionals, for loops, and whatnot, you just use your primary language.
In Dart's case, you also win with the typing: if a widget expect a callback that receives a User instance and returns an integer, you can define that and making sure that instead of runtime errors, you will see the errors in your IDE as you type.
You also don't need to worry about different naming conventions. If you app calls it userIds, your UI will also call it userIds, instead of "user-ids", or "user_ids".
How is it better than Gradio, and what additional features does it have?
Is that what we can expect performance wise? What causes this?
>Thanks! We're building a hosting service that you can deploy your apps to. Our plan is to have a free tier for your first app, then charge for additional apps. We're still finalizing this, so would love to hear any thoughts.
this is a neat demo but why do I need to get python in the client when it is even easier to get js in the server?
webdev is basically a solved problem at this point
You're headed into a place where some customers may confuse you.
- NiceGUI was initially build for accessing and controlling hardware as shown in our webcam demo); I'm not sure how it would be done with Pynecone
- NiceGUI encourages the use of standard Python (callbacks, if-statements,..), Pynecone on the other hand uses explicit State classes and provides constructs like pc.cond and pc.foreach.
- NiceGUI uses Vue/Quasar for the frontend while Pynecone is build on NextJS
- NiceGUI generates HTML/JS/CSS via templates on the fly while Pynceone has an explicit compile step; so NiceGUI can be run with normal "Python" instead of using a command like "pc"
- while both frameworks use FastAPI for the backend, in NiceGUI you can actually use your own App and simply extend it with NiceGUI to provide additional UI; Pynecone hides FastAPI which makes it harder to provide other API endpoints (for example to serve images from memory instead of files).
By using Python in the frontend you mean the Python is transpiled into JS? The frontend uses templating or generates a SPA app?
Here's one of their examples https://pynecone.io/docs/getting-started/introduction
I don't really care about HTML/CSS/JS. I really don't care about React. But the four of those form this gigantic cottage industry of tribal knowledge that requires so much fiddling. In short, I don't want to be a webdev.
I just want to use the browser as a dumb display device and a software delivery mechanism. I want the UI to be as simple as possible until I start getting traction, then I'll get someone to add some paint to make it passable.
The dream is a VB-like product that lets me focus on creating features, not worrying about technical inanities like getting CORS configured right for the 5000th time.
The catch is trying to keep up with Javascript complexity. Javascript/react world is entirely different beast. Spent some time understanding class based React. But then things moved to hooks. I sort of started grokking hooks. But now there is new clamour (not yet mainstream) about something new like server side components or signals or hydration or what not. Same is the case with Svelte. I tried the basic tutorials, understood it. But Svelte kit started talking about 100 different ideas about server pre-rendering components etc. I thought why bother? Jinja2 templating and bit of inline JS looked a better option.
Python devs want to stick to Python because it is still second best language to get something out there, quickly. Except for UI. Currently I'm looking into using HTMX as much as possible. If this thing solves for UI side of it then I'll definitely give it a try.
One thing that is a huge win for the work I am doing - using Dash, I'm able to prototype an informal API and build the visualisations in a single step, which is great when it's unclear what is going to be useful. Long-term it definitely makes maintenance harder, and I think that's where there is a gap in the ecosystem - ideally I want to eject the front-end and convert the API to something more formal to hand off to a real front-end developer.
Not easy, esp. when you throw in CSS and the build systems
Very hard. Of course I can just write everything into a big js file, but if you want to structure things, it's hard. You have to learn all about this NPM and NODE stuff, learn how to refresh and debug things.
And if you make the tiniest mistake, this thing will not crash with proper error messages like python.
I get that nerds like to write code, but it is really depressing that we still can't just point and click and share content on the internet, we need to hire a nerd to write some special language just to make some text boxes and images show up on a screen. I mean, it's 2023. We have rovers discovering ice on freaking Mars. But just making a web page by pointing and clicking is impossible, or limited only to specific web hosting companies.
Historically the 4GL/nocode/lowcode movement has been a miserable failure, and not for lack of attempts to push that idea down people's throats.
But note there is one area where GUIa are used for coding: game development. But Unreal 5, Unity etc. don't exactly have a simple GUI.
Joke aside, some say that with AI... Writing code is getting ever easier... Even easier than using a nocode tool.