Cotton - a component based design system for Django

I started a Python/Django position a year ago transitioning from PHP/Laravel and a number of frameworks there. I found Laravel’s blade components (and JS framework style frontend composition in general) very powerful and productive concepts for spinning up interfaces.

Fuelled by the lack of such a thing I wanted in the Django eco-system I built cotton alongside a project and now feel like it’s really helping me make light work of building capable and re-usable frontends in Django and would like to share it with the community.

docs site: https://django-cotton.com

repo: https://github.com/wrabit/django-cotton

Any feedback welcome!

15 Likes

This is a cool concept. I’m interested in playing around with it and possibly helping contribute. Nice work, I’m excited to see where this goes.

1 Like

Thanks, I’d like to provide more usecase examples. I noticed you’re familiar with htmx and that could be a good topic to cover. Using the ‘{{ attrs }}’ in a component will allow you create reusable inputs which you can easily pass down htmlx attributes to the base input element.

But my knowledge of htmx is fairly limited. I’d be interested to hear about your experience using cotton. Thanks for the first PR too :ok_hand:

2 Likes

Love the concept :smiling_face: I wonder if you tried some of the similar packages out there, and if so what’s your thoughts on how Cotton differs? See the list of template-related packages on awesome-django.

Personally I have mixed feelings about Cotton components using the same syntax as vanilla HTML custom elements. Feels like it’d make it harder to know what’s what? And could be problematic for any HTML linting.

1 Like

Thank you, I researched a few and tried a couple at the start, from jinjax (requires jijnja templates and I found no documentation for setup with django) also django-components (a bit too heavyweight and I don’t require data component setup, just quick partial creation and reuse with slots and named slots.) I also wanted the ‘{{ attrs }}’ feature which helps a lot designing custom inputs.

About the syntax, I think quite the contrary, you don’t need any specific plugins in your IDE/editor as the tags are already xml-like so you get auto completion in full and self closing tags.

It’s certainly a paradigm shift for some but for those who have already built js frontends ala svelte, vue then it’s already familiar.

So far I’ve only really gone through the quick start so I haven’t tried using it with HTMX yet, but that’s something I’m interested in trying out. I think HTMX, Alpine (which I still need to learn) and Cotton could be a pretty cool combo.

One thing I’d like to try is using Cotton as a dependency in a separate third party application. Cotton has it’s own project level settings/configurations, so I think that would make it a little bit tricky for me to justify using it in my own 3rd party application, but I’ll try it out and see if I could make any suggestions to make that smoother.

I think some additional usecase examples and references would be great. I understand the docs site is brand new though, so no rush.

1 Like

That’s such a cool project! Thanks for contributing.
I would like to have a go locally and also contribute, but haven’t found any instructions on how to “develop locally”.

1 Like

Thanks @leandrodesouzadev, I’ll be adding a contributing doc soon, will ping you when ready :+1:

Comparison table now up at GitHub - wrabit/django-cotton: Bringing component-based design to Django templates

Hi @leandrodesouzadev I’ve now included a contributing doc as discussed

Thanks

1 Like

I’ve been looking for something like this so thank you @wrabit for building it.

I’ve got a basic example working (a component) but am finding that tailwind changes don’t register, even when running a watcher. Has anyone else experienced this?

I’m using the tailwind CLI through pytailwindcss

1 Like

Hi Luco, thanks for the comment, I’ve got no experience in that package but when using base tailwind and specifying .html in your content setting in tailwind.conf.js it works just fine on my side.

Hi, found the error.

I’m using a root level templates directory and had improperly configured tailwind.config.js so it wasn’t watching subdirectories of template - and hence any changes in the ‘cotton’ subdirectory.

This line fixed it: content: ["./templates/**/*.html"],

I am the author of the django-viewcomponent and I’d like to share some of my thoughts here.

django-cotton’s syntax seems very similar with Laraval/PHP, and it help developer to create reusable component with Django template.

But Django template supported syntax is not that powerful than Laravel, you can take a look here: Blade Templates - Laravel 11.x - The PHP Framework For Web Artisans

So only using django template to create component would make it can not handle a more complex logic very well in some cases.

Another project GitHub - mixxorz/slippers: A UI component framework for Django. Built on top of Django Template Language. also has this problem.

To solve the problem, they need to import other syntax or template tags, which make things more complicated.

In my opinion, a good server side component solution, should better combined with Python code and Django template code.

  1. The Django template is only used to render the value of the component.
  2. All logic should be put in Python code, leveraging OOP

And I recommend this blog post How we use Web Components at GitHub - The GitHub Blog

Github.com has met more complicated problems then many of us, and I think the https://viewcomponent.org/ is a promising solution for Django developers.

@michael-yin I think we already had this conversation on reddit :slightly_smiling_face: but to say it again - This project was not inspired by the same pattern you refer to. It’s not intended to be a ‘server side component solution’. There is already django-components and others for that.

This project was built to add functionality similar to modern UI composition found in Vue, Svelte and Laravel’s anonymous blade components - which I find a very powerful concept allowing me to create UI’s very quickly and optimally re-use code thanks to the simplicity of some basic concepts:

  • slots
  • named slots
  • dynamic slots
  • attributes
  • props

and cotton does that well…

  • without needing to create a separate backend component
  • without needing to register a component
  • whilst enabling other possibilities normally restricted with django’s native tags

Think of cotton as crafting your UI with re-usable partials that are configurable. You will end up writing less code and improving DRY / maintainability. It’s not about backend components.

Django template provides enough capability to execute this concept just fine.

2 Likes

Let me first say that the library looks very nice, and I’d love to take a deeper dive and try it out (probably won’t happen for a while, unfortunately). And I can see it’s already taking off :slight_smile:.

I’m a heavy user of django-components, among other stuff related to the topic I would say. So I really understand where @michael-yin is coming from.
Do you have any specific arguments against having an optional in-between .py component logic, or is it just your preference? On a first glance, I would chose Cotton syntax over django-components syntax, but I have too many use cases where I don’t want some component logic cluttering my templates or views.

As for server side component solution, the goal is to make the component code readable, maintainable, so it can be better reused.

Using a Django command to create both .py and .html for a new component is easy and it wont take developers much time.

But if the server side component solution can not benefit with Python syntax, then the ability would be limited in some cases.

Please check this button_component from GitHub’s GitHub - primer/view_components: ViewComponents for the Primer Design System it is server side components used by GitHub.com

  1. view_components/app/components/primer/button_component.rb at 399a50f2398107cc58b23e4281f41513f660c836 · primer/view_components · GitHub
  2. view_components/app/components/primer/button_component.html.erb at 399a50f2398107cc58b23e4281f41513f660c836 · primer/view_components · GitHub

Even the code is for Ruby on Rails, I can still understand the logic and the component template is clean.

And you can also ask if you only have Django template can you have good way to make it clean and easy to read?

To know more details behind Github ViewComponent, you can check this video, which inspired me to port it to Django community.

This is by so far another exiting thing that i found in the django community. I’ve been recently having difficulties picking a ‘solution’ for this problem, there are some options there as I see, but still did not able to find a ‘ideal’ option. I saw about cotton today in the bytebugs Youtube video and come here by search. I will try out cotton and will come back with my ideas.

1 Like