инструменты, которыми пользуешься каждый день: не хочется ничего устанавливать, регистрироваться или терпеть рекламу — просто открыть и сделать дело.
−куки-модалы, рекламные баннеры, непрозрачный сбор данных
−«зарегистрируйтесь, чтобы использовать эту базовую утилиту»
−отправка jwt-токенов на чей-то загадочный сервер
+работает в браузере — без сетевых запросов для базовых инструментов
+один клик с главной, без регистрации, без тёмных паттернов
+открытый код, проверяемый, деплоится куда угодно
// стек технологий
$catstack.txt
# стекastro· генератор статических сайтов, ноль js по умолчанию
css· ванильный, custom properties для тем
typescript· типы каталога и build-time логика
fonts· fraunces, inter tight, jetbrains mono
icons· tabler icons (open source, mit)
hosting· статика, деплоится куда угодно
analytics· cloudflare web analytics # без кукисов, только агрегат# чего нет× react / vue / svelte
× трекинг-пиксели, ретаргетинг, реклама
// вопросы
безопасность и приватность
Q.где именно обрабатываются мои данные?+
для всех базовых инструментов (JSON, JWT, Base64, регулярки, хеши и т.д.) — исключительно в браузере. обработка идёт через JavaScript и WebCrypto API прямо на твоём устройстве. токены, ключи api и содержимое логов физически не могут покинуть вкладку, потому что для этих операций нет никакого backend'а.
для Pro облачных функций (пакетные задачи, обработка больших файлов, REST API) данные отправляются на изолированный сервер, обрабатываются в памяти и сразу удаляются — никаких логов, никакого хранения.
Q.есть трекеры, реклама или куки?+
ничего. ни Google Analytics, ни Facebook Pixel, ни скриптов ретаргетинга, ни сторонних кукисов. единственная аналитика — Cloudflare Web Analytics: без кукисов, только агрегат (какие страницы открывают, из какой страны). никакого доступа к тому, что вставляешь в инструменты. баннера с кукисами нет — нечему соглашаться.
Q.whittly работает офлайн?+
после загрузки страницы — да, все базовые инструменты работают без интернета. self-hosting ещё проще: клонируй репозиторий и раздавай статические файлы любым удобным способом.
pro и цены
Q.зачем платные планы, если базовые инструменты бесплатны?+
базовые инструменты работают в браузере и почти ничего не стоят в обслуживании. но облачные функции — пакетная обработка, большие файлы, REST API — требуют реального серверного вычисления. платные тарифы существуют только для покрытия этих расходов. не для рекламы, не для сбора профиля, не для lock-in. бесплатный план остаётся полным и полезным навсегда.
Q.сколько стоит pro?+
Pro — 390 ₽/мес или 2 900 ₽/год (~2 месяца бесплатно). API — 1 990 ₽/мес или 14 900 ₽/год. оба тарифа скоро будут доступны — оставь заявку на странице тарифов. также доступны цены в USD для глобального рынка.
Q.где хранится история pro-аккаунта?+
по умолчанию история хранится локально в браузере. если включить облачную синхронизацию в pro-аккаунте, она будет зашифрована и сохранена на серверах. экспортировать или удалить её можно в любой момент.
философия
Q.почему «whittly»?+
to whittle — это медленно срезать дерево острым ножом, пока не получишь нужную форму — ничего лишнего. подходит для проекта о небольших, острых инструментах и о том, чтобы срезать шум с большинства сайтов для разработчиков: баннеры, модалы, загадочные серверы, тёмные паттерны. режь, пока не останется только полезное.
Q.можно добавить свой инструмент?+
да, пожалуйста. каждый инструмент — один самодостаточный модуль. открой issue с описанием того, что хочешь добавить, или сразу отправь pull request.
[{"name":"timestamp converter","slug":"timestamp-converter","desc":"unix ↔ date, iso 8601, utc, relative","cat":"convert","icon":"ti-clock-2"},{"name":"csv ↔ json","slug":"csv-json","desc":"convert csv to json and back, auto-detect delimiter","cat":"convert","icon":"ti-table"},{"name":"xml ↔ json","slug":"xml-json","desc":"parse xml into json and back","cat":"convert","icon":"ti-arrows-shuffle"},{"name":"number base converter","slug":"number-base-converter","desc":"decimal, binary, octal, hex and any custom base","cat":"convert","icon":"ti-number"},{"name":"json formatter","slug":"json-formatter","desc":"prettify, minify, validate, tree view","cat":"format","icon":"ti-braces"},{"name":"base64","slug":"base64","desc":"encode and decode, text or file","cat":"encode","icon":"ti-binary"},{"name":"url encoder","slug":"url-encoder","desc":"percent-encode and decode url components","cat":"encode","icon":"ti-link"},{"name":"hash generator","slug":"hash-generator","desc":"sha-1, sha-256, sha-384, sha-512 via web crypto","cat":"encode","icon":"ti-shield-lock"},{"name":"html entity encoder","slug":"html-entity-encoder","desc":"escape and unescape html special characters","cat":"encode","icon":"ti-code"},{"name":"bcrypt","slug":"bcrypt","desc":"hash and verify passwords with bcrypt","cat":"encode","icon":"ti-lock"},{"name":"jwt decoder","slug":"jwt-decoder","desc":"decode tokens, inspect claims","cat":"encode","icon":"ti-key"},{"name":"uuid generator","slug":"uuid-generator","desc":"v4, v7, nanoid, custom","cat":"generate","icon":"ti-fingerprint"},{"name":"password generator","slug":"password-generator","desc":"configurable length, charset, entropy score","cat":"generate","icon":"ti-password"},{"name":"text diff","slug":"text-diff","desc":"line-level diff between two texts","cat":"text","icon":"ti-file-diff"},{"name":"case normalizer","slug":"case-normalizer","desc":"camelCase, snake_case, kebab-case, PascalCase and more","cat":"text","icon":"ti-letter-case"},{"name":"regex tester","slug":"regex-tester","desc":"live match highlighting, explain mode","cat":"text","icon":"ti-regex"},{"name":"slug generator","slug":"slug-generator","desc":"url-safe slugs from any text, supports cyrillic","cat":"text","icon":"ti-slash"},{"name":"string inspector","slug":"string-inspector","desc":"length, bytes, unicode, entropy, character frequency","cat":"text","icon":"ti-text-scan-2"},{"name":"cron parser","slug":"cron-parser","desc":"translate schedules to english","cat":"data","icon":"ti-clock-bolt"},{"name":"curl converter","slug":"curl-converter","desc":"convert curl to fetch, axios, python requests","cat":"data","icon":"ti-terminal"},{"name":"query string parser","slug":"query-string-parser","desc":"parse and build url query strings","cat":"data","icon":"ti-list"},{"name":"mime lookup","slug":"mime-lookup","desc":"find the right mime type for any file extension","cat":"data","icon":"ti-file-type"}]