Convexを好きになるまでの道のり

ソフトウェア開発・プログラミング
この記事は約88分で読めます。

この動画は、人気YouTuberであるTheoがConvexという開発プラットフォームに対する認識を根本的に変えた体験談である。当初はConvexを「おもちゃアプリ向け」と軽視していたTheoが、4年の歳月を経て完全に評価を覆し、自身の主要プロダクトであるT3 Chatの基盤技術として採用するまでの経緯を詳細に語っている。Reactがフロントエンドのプリミティブを革新したように、Convexはバックエンド開発の根本的な概念を変える新しいパラダイムを提供するという視点から、従来のSQL中心の開発からTypeScript中心のデータレイヤーへの移行がもたらす開発体験の劇的な改善について論じている。

How I fell in love with a database (I hated it for 4 years)
Convex is one of those products I just kinda wrote off. At least until people I trusted started using them. I finally ga...

Convexに対する長年の誤解から真の理解への転換点

皆さん、お疲れ様です。これは長い間、多くの方々にお待ちいただいていた動画の一つです。今日は私の新しいお気に入りのデータベースプロバイダー、バックエンド、同期エンジン、そしてライブラリセットなど、本当に多岐にわたるサービスについてお話しします。

もちろん、Convexのことです。私がこの時点で実質的に2回も移行したデータベースであり、徐々に愛するようになったすべての理由についてお話しします。

本題に入る前に少し背景をお話しすると、Convexはアプリケーションの構造について異なる考え方を提案しています。以前のキャッチコピーは「Reactアプリのもう半分」でした。なぜなら、これはフロントエンド以外のすべてを担当し、その役割を非常に優れた形で果たすからです。

しかし、私は常にConvexが行っていることについて、かなり懐疑的でした。2021年に初めて実際に触って、彼らのオフィスで時間を過ごした時、私はほぼ即座に「これは私には合わない」と結論づけました。これは玩具アプリや初心者が素早く何かを組み立てるためのソリューションだと思ったのです。

当時はまだ非常に初期段階だったので、私の判断は完全に間違いではなかったかもしれません。しかし、その考えをこれほど長い間持ち続けたことは、本当に後悔しています。

T3スタックの誕生とTRPCとの出会い

私がどれほど間違った見解を持っていたか、どのようにしてConvexをより真剣に検討し始めたか、そして最終的にConvexに深く恋に落ち、現在ではT3 Chatのすべて、そしてそれ以降に構築したもののほとんどで使用するソリューションになった経緯をお話ししたいと思います。

Convexは、私が構築するもの、何を構築するか、そしてユーザーに提供する体験について、格段に良い気持ちを与えてくれました。そして、彼らをチャンネルのスポンサーと呼べることを非常に幸運に思います。実際、それが物語の重要な部分でもあります。

とはいえ、この動画は可能な限り偏りのないものにしたいと思います。そのため、Convexはこの動画のスポンサーではありません。それでも、チームにお給料を払わなければなりません。エディターも給料をもらう必要がありますからね。

この旅は、記憶が確かなら2021年12月頃から始まりました。もう少し遅かったかもしれません。彼らのオフィスでミートアップがあり、私が本当に話したい、一緒に過ごしたいと思っていた2人のスピーカーがいました。

その時点では、Convexについて本当に何も知りませんでした。知っていたのは、私が本当に楽しみにしていた素晴らしい講演を主催しているオフィスだということだけでした。正確には複数の講演でした。Solidの作者であるRyan Carneato氏と、Bunの作者であるJared Sumner氏でした。名前の綴りが正しいことを願います。

これはJared氏の初めての講演だったと記憶しています。文字通り初めてでした。Ryan Carneato氏の講演は、私が以前に見たことのある内容の多くを含んでいましたが、二人とも彼らの取り組みについて熱心に語るのを見ることができて、本当に興奮していました。Ryan氏に実際に会うのは初めてでした。彼と一緒に過ごすのは初めての体験でした。本当に良い時間でした。

とはいえ、同じ頃、私の人生に別の大きなことが起こっていました。T3スタックが話題になり始めていたのです。正直に言うと、出来事の順序を正しく把握できれば、これが最初だったでしょう。そして、これは11月だったでしょう。

2021年11月、私はT3スタックを作り出しました。私は既にt3.ggというドメインを所有していました。他の人たちが言うことに反して、3つの「T」は私の名前のT以降の3文字を表しています。

私は3Vという友人にインスパイアされました。彼の名前はWernner V何とかで、ドイツ語でWはダブルVなので、ダブルVが彼のイニシャルで、それは3つのVでした。それで彼は3Vと名乗っていました。私は彼のドメインが大好きで、とても嫉妬していて、それが無意識のうちに、t3.ggが利用可能だと分かった時に取得することにつながりました。私が単に3Vをコピーしていたことに気づくまで、1年かかりました。

とにかく、T3は私のブランドであることを意図していました。それ以来、はるかに大きく発展しましたが。TailwindとTypeScriptとTRPCの3つのTを表していると考える人を責めることはしません。なぜなら、それは論理的に理にかなっているからです。

私がT3スタックを作った理由は、LAMPの時代に育ったからです。その後、大学でMEANの時代を経験しました。それがMERNの時代になるのを見ました。私はこれらのスタックに慣れ親しんでいました。これらは時代と文化、そしてそれ以上の多くのものを表していました。私はこれらのランダムな略語を通して、自分の開発の旅路をほぼ測ることができました。そして、それが恋しかったのです。そして、本当にクールな機会を見ているような気がしました。

私は自分のフロントエンドアプリでバックエンドコードを書くための独自のソリューションの提案を書いていました。この提案を4年前に書きました。これは2021年7月でした。これはping.ggというビデオ通話アプリの構築を始めた頃でした。そして、エンドポイントを書いて、それをReact Queryで呼び出し、物事の形について知らないことにイライラしていました。

私はTwitchから出てきたばかりで、そこではすべてにGraphQLを使用し、codegenを使用して信頼性のある型定義を取得していました。そして、それをとても恋しく思っていました。

useBackend提案からTRPCへの道のり

当時の私のスタックは、すべてのデータフェッチにReact ViteとReact Queryを使用し、エンドポイントはランダムなTypeScriptバックエンド関数をホストするためのVercel APIディレクトリを使用して定義されていました。

そして、Next.jsに移行し始めました。Next.jsが提供するものではなく、Next.jsアプリにAPIディレクトリを配置でき、それらすべてを1つのパッケージにバンドルして、デプロイが面倒でなくなるという特性のためでした。デプロイを簡単にするためにNext.jsに移行したのです。Next.js自体のためではありません。ばかげているように聞こえるかもしれませんが、それが私の旅路でした。

しかし、データをアプリに取得する方法にますますうんざりしていました。データをアプリに取得し、データが正しい形で、想定通りに動作することを確認するためのさまざまな方法について、あまりにも多くの時間を費やしていました。

これが私が書いた提案です。Reactコードで、バックエンドからデータが必要な場合、use backendと書きます。一意のキーを与えます。バックエンドコードに必要なことは何でもします。この場合、get profile from DBはおそらくPrismaを叩く関数だと想定しています。当時私はPrismaの大ファンでした。

データを返し、prefetch trueとします。そして今、このTypeScriptコードで、dataの型を推論できます。なぜなら、ここにあるからです。そこで返されるもの、それが何であれです。

開発中は、フロントエンドがバックエンドからの型定義を持っているという最高クラスの体験を得られます。なぜなら、バックエンドコードをまさにそこに書いているからです。

そして、コンパイル時に、これを2つのファイルに分割します。例のページ機能で、同じキーを使用するuse queryコールにホットスワップされた、この生成されたエンドポイントをフェッチする、データを返すものを作成し、データをJSONに変換して返し、get serverside props関数を通して初期データを渡すことができ、この関数も自動生成されてこのデータをフェッチし、関数を呼び出すかエンドポイントを叩いて、サーバーレンダリング時にそこにデータを置くことができます。

そして、実際に関数を呼び出して返すだけの、キーに付けた名前を使用する生成されたエンドポイントを定義します。

これは、私のバックエンドコードをより簡単に書く方法の簡単なスケッチであり、結果として、より良い型安全性、より良い構成可能性と信頼性を得ること、そしてget serverside propスタッフが組み込まれているより良いパフォーマンス特性も得ることを意図していました。私はこの提案に本当に興奮していました。

私がフォロワーもいない頃にTwitterを閲覧していた時、そして実際これはさらに遡ります。これらを下に移動させる必要があります。私たちは今、2021年7月にいます。この旅は本当にクレイジーです。私は自分のuse backend提案にとても興奮していました。そして、React Queryの作者であるTanner Linsleyが、Twitterスペースを行っているのを見ました。参加しました。

いろんなことについてたくさん話しました。思い出してください、当時私は最大200フォロワーしかいませんでした。動画も投稿したことがありませんでした。クリエイターではありませんでした。私はTwitterをもっと使い始めた単なるランダムな開発者で、コロナ禍で発狂していました。なぜなら、とてもオタク的に盛り上がりたかったからです。

オタクな同僚との昼食や夕食の会話を失い、テクノロジーで面白いと思うこと、そして書いているこれらのクレイジーな提案やその他起こっているすべてのことについて話したかったのに、場所がありませんでした。それで、これらすべてについて話すためにTwitterスペースに本当にハマりました。

それで、Tannerのスペースに参加し、他のいろいろなことについて話した後、少し時間が残っていました。私は彼に私の提案についてどう思うか尋ねました。彼は運転していました。それが彼がスペースを主催する時でした。ただ仕事の行き帰りの運転中に、通常は。

そのため、提案を見せることはできませんでしたが、それについて説明し、他の人が見に行けるようにリンクしました。私が彼にそれについて尋ねた後、彼の反応は、現在ここにいるすべての人にとって非常に重要でした。

Tannerは大体こう答えました。「それはかなりクールに聞こえますね。React Queryで構築している似たような2つのものを知っています。BlitzとTRCPか何かと呼ばれていると思います。」

それから、彼はまだそれらを調べる機会がなかったが、新しい技術について私と話すことを本当に楽しんだと述べました。そのため、彼は非常に丁寧に、彼の言葉を借りれば、私に宿題を出すつもりだと要求しました。

彼は私にそれらを調べて、次のTwitterスペース中に戻ってきて、発見したことすべてについて話し、これらが何であり、何をするのかを彼がよりよく理解できるようにしてほしいと頼みました。

そうしました。実際、起こったことは、Astroに気が散ったことです。Astroで一からサイトを構築しました。数日かかると思っていました。1時間くらいかかりました。Astroに恋をしました。それを出荷しました。午後8時頃に終わりました。そして、このハッキングのために週末全体を確保していたのに、予想よりもずっと早く終わりました。

それで「よし、ついにこれらのBlitzとTRPCの事を確認してみよう」と言いました。

実際、TRPCから始めました。ホームページに行った時、「構文は何?ここで理解できないことがたくさん起こっている。どうやって始めるかを見てみよう」と思いました。

一からセットアップしようとしましたが、当時は非常に困難でした。あまり進まず、「これは私には向いていないかもしれない。彼が言及した他のものを確認してみよう」と言いました。

そこで、BlitzJSを確認しました。BlitzはNext.js用の足りないフルスタックツールキットでした。即座に「これはまさに私が望んでいるものではないか?」と思いました。調べ始めました。

当時、BlitzはNext.jsをフォークしてRailsやLaravelのようなものにより触発された新しいオールインワンフレームワークを構築する過程にありました。認証からデータベース、ORMから、サーバーからクライアントにデータを取得するパイプラインまで、必要なものすべてを提供することを望んでいました。

彼らはあなたのためにすべてを行い、多くの意見と、あまり多くないモジュラリティでそれを行いました。そして、一から新しいアプリを構築する新しい方法だったため、段階的に採用することは基本的に不可能でした。

私はそれを見て、有効にされたパターンは見ましたが、それが私から奪った量は好きではありませんでした。それは私から多くのコントロールを奪いました。これがテーマであることに気づくでしょう。これを嫌った理由を覚えておいてください。

私は、すべてを私に規定するソリューションは望んでいませんでした。Railsは望んでいませんでした。過去から慣れ親しんだものが欲しかったのです。再びLampスタックが欲しかったのです。MeanやMernスタックやこれらのさまざまなものが欲しかったのです。慣れ親しんだものが欲しかったのです。

あるツールを別のツールと交換できる、理にかなった時にできるモジュラーツールのアイデア。そして、Blitzは当時まったくモジュラーではありませんでした。

それで、私の選択肢が何であるかを理解しました。私が必ずしも同意しない多くの意見で、私のアプリを乗っ取るであろう、この非常にモノリシックな方法を取ることができました。または、男らしくなってTRPCオンボーディングを突破することができました。そうしました。

私のコードベースでTRPCを使って物事を書き直し始めました。そして、ほぼ即座に恋に落ちました。動作させた後、それはクリックしました。そして、一度クリックしたら、完全に夢中になりました。

そして、人々はそれを理解しませんでした。それを人々に説明する時、私は狂って聞こえました。

バックエンドで関数を書いて、フロントエンドでそれを呼び出すだけで、バックエンドで変更すると、フロントエンドがすぐに変更を見るというようなものでした。FirebaseのTypeScript版を約束しているように聞こえましたが、意味がありませんでした。人々は理解しませんでした。

T3スタックの誕生とYouTubeチャンネルの開始

その後、現在もここにいる可能性のある友人Jacob Evansに提案しました。彼は別の本当に多産なTypeScript開発者で、さまざまなオープンソースのものに貢献しています。

彼も理解しませんでした。そこで、私は彼のオープンソースプロジェクトの1つを取り、Tailwind、Next.js、TypeScript、そして最も重要なTRPCを含む、現在使用している私のテクノロジーを使って一から書き直しました。

私は彼の8,000行のFirebaseのめちゃくちゃなプロジェクトを、超シンプルな500行のTRPC OG T3スタックコードベースで書き直しました。

彼がそれを見た時、すぐに圧倒されました。そして、単にそれがどれほどクールかを言うだけでは、これを人々に説明できないことを理解しました。コードを見せなければなりませんでした。

それがT3スタックが始まった時です。そして、さらに重要なことに、それが私のYouTubeチャンネルが始まった時でした。

この動画は2021年11月30日に投稿されました。私はスタックがどれほどクールかを人々に見せたかったので、特にこの動画を作りました。そして、元々は動画でさえありませんでした。人生で初めてコードを書くストリームをすることにしました。

実際、17歳の時にコンテスト用のゲームを作っているストリームを1回したことがありました。10年前に、1回だけコードを書くストリームをしたことがありましたが、自分をコードストリーマーとは考えていませんでした。少しストリームしていました、主にゲームとチャットでしたが、コードストリームをしたことはありませんでした。

私がこれをしたのは、話していた人々、これらのTwitterスペースでたむろしていた小さなグループの人々に、私のスタックがどのように見えるかを見せたかったからです。そして今、285,000回再生されています。

動画を録画していたわけでもありませんでした。構築が好きなものと、それらでどのように構築するかについて、ただオタク的に興奮していただけです。そして、OG Theoの髪から、それ以来どれだけ遠くまで来たかを見ることができます。ああ、神様、私の肌。Accutaneをしたことに本当に感謝しています。

とにかく、私がここで言いたいポイントは、この モジュラーなツールセットがどれほど強力かを見せたかったということです。私はそれをT3スタックと名付け、そして今日、私たちはすべてここにいます。このチャンネルは、この旅とこれらすべての要素がなければ存在しませんでした。

Convexについてもまだ言及していないのに、これは必要以上に詳しすぎます。しかし、思い出してください、私たちはConvexと私がどのようにしてそれにたどり着いたかについて話すためにここにいます。

私は知識をダンプする機会を使っていますが、この知識ダンプは私が何を気にかけていたかについてのコンテキストを与えるのに役立つと思います。これが私が望んでいたものです。私がT3スタックと名付けたものから得たこのレベルのモジュラリティが欲しかったのです。

構築する時に、このレベルのモジュラリティが欲しかったのです。なぜなら、それが理にかなう時に、他の部品と部品を交換する能力が欲しかったからです。そして、それは実現しました。

私たちはPrismaをDrizzleに置き換え始めました。驚くべきことに、残りはかなりよく持ちこたえています。要点は、私はこのレベルのモジュラリティとコントロールが欲しかったということです。理にかなって、うまく組み合わさり、私と私のチームが速く、そして自信を持って出荷できる方法でアプリケーションを構築するために使用できる、構成可能な部品が欲しかったのです。

そして、私はこのスタックを本当に誇りに思っていました。そして、それはしばらく話題になりました。元々Nexelによって作成され、その後素晴らしい貢献者とコラボレーターのセットによって維持されているinitツールがあった短い期間がありました。その多くがここにいて、create T3 appが一時的にReactアプリを立ち上げる3番目に人気のある方法でした。

それは信じられないほどうまくいきました。私、そしてもっと重要なことに、皆さんコミュニティがT3スタックで起こらせたことを本当に誇りに思っていました。そして、これにより、私はいくつかのアイデアにコミットしました。

モジュラリティを妥協させるものは何も受け入れませんでした。私は常にLinuxイデオロギーに染まっていました。想定されることを行う小さな部品が好きで、それを自分で組み立てることができます。

フルスタック型安全性について妥協することはありませんでした。ある関数が何かをすると思い、他のコードが別の何かをすると思うような方法でコードを書くことを許可しませんでした。回避できるのであれば、どのシステムでもそれを決して許容しません。

私は本当に単一の真実の源が欲しかったのです。そのため、コードで記述されているものは、理想的には1か所でのみ記述されるべきです。これはDRY(Don’t Repeat Yourself)ではありません。

明確にするために、異なるもののために自分自身を繰り返すことは問題ありません。あることを行う関数があり、別のことを行う必要がある場合、条件を追加すべきではありません。関数をコピーペーストすべきです。それは私には大丈夫です。

私が話しているのは、関数がいくつかのデータを返す場合、それが返す型を5か所でコピーペーストすべきではないということです。なぜなら、今度はそれが全く意味をなさない時に、しなければならない保守作業がずっと多くなるからです。

私は真実の源がコードベース全体に分散されることを好みません。そのため、私はコードベースのルールや期待が1つの場所にエンコードされ、可能な限りそこから導出されることを確実にするために、自分の能力の範囲内で努力します。

この時点で、人々は実際に私に注意を払い、私が誰であるかを知り始めています。私はRyanとJaredとのこのオフィストークに招待されました。

Convexとの初回の遭遇とその誤解

再び、オフィストーク、これはConvexオフィスで、私はこの時点でConvexについて何も知りませんでした。講演が終わりました。私たちはすべて後で雑談しています。Convex従業員が私に近づいてきました。思い出すに、それはTomでした。

「あなたはTRPCの人ではありませんか?」

彼がTRPCの大ファンであることが判明しました。特に、私のおかげで今見始めている成功に。バックエンドとフロントエンドが完全にお互いを認識するようにTypeScriptを書くこのアイデアは、彼と彼らがConvexで行っていることにとって非常に興奮させるものでした。

そして、彼は私にかなり率直に言いました。「私たちはConvex用のSDKの設計について、TRPCに非常にインスパイアされました。」彼はConvexが何であり、どのように動作するかについて簡単な概要を教えてくれました。

そして、私には、それはBlitzがクローズドソースのスタートアップだったらどうなるかのように聞こえました。そして、私はこのアイデアをとても嫌いました。これは私にとって史上最悪のことでした。

なぜなら、私がこのスタックを構築したのは、このよりモノリシックなデザインのアンチテーゼであるためだったことを思い出してください。そして、彼が説明したものは、さらなるロックインがあるもののように聞こえました。私はロックインを嫌いました。

私は、移動できない方法で物事を書くというアイデアを嫌いました。それらは移植可能ではないでしょう。そして、彼がConvexを説明して私が聞いていたすべてが、正直に言うと、彼らがTRPCのような最良の部分を盗み、それらをクローズドソースのコードベースに入れ、何も貢献せず、サイドプロジェクトやスタートアップにはクールだが私には向いていないものを作ったように聞こえました。

そして、膨大な時間が過ぎました。膨大な時間です。今、私たちは、これは推定ですが、2024年6月にいます。DMを調べる気はありません。

Tannerとキャッチアップチャットをしました。多くのことが起こっていました、ドラマとか諸々。私たちの分野ではそういうものですよね。TannerとIがキャッチアップしています。

彼は言いました、「ところで、私はちょうどConvexオフィスにいました。あの人たちは特別です。彼らは本当に自分たちが何をしているかを知っています。」

私はTannerからこれを期待していませんでした。Tannerは私の親しい友人の一人です。今日でも彼を尊敬しており、おそらく常にそうでしょう。私が今まで会った中で最も賢く、思慮深く、徹底した開発者の一人です。

Tanstack Startが実現する時、それは状況を変えるでしょう。それが本当に準備ができた時、彼が私たちに知らせてくれる時、物事は本当に速く、大幅に良くなるでしょう。彼はとても気にかけており、とても思慮深いのです。

そして、彼は嗅覚テストに合格しないものを無視するのも非常に早いです。そして、彼はそれについて怒りません。ただ先に進みます。

何かが彼が考える方向に行かず、彼が持つ期待に応えないと理解した時、彼はそれを修正しようとしません。ただ先に進みます。時々、彼は自分のものを構築します。時々、彼は完全に別のことをします。彼は時間を無駄にしません。

だから、Tannerが私のところに来て、これは信じられないと言ったのは、確実に「くそ、私は再考すべき」瞬間でした。

その直前、そして私はこれのタイムラインを全く覚えていませんが、私はwebdev codもConvexにより入り込んでいるのを見ていました。そう、なぜ私はSupabaseよりConvexを使うのか。これは2024年2月でした。だから私はこれを見て、Convexにより興味を持つようになりました。

私が信頼するCodyのような人々がそれをより多く持ち出し、それからTannerが、私にとって非常に尊敬される人物が、彼らを真剣に受け止めていると私に言いました。

私はここからここまでの間、Convexに全く注意を払っていませんでした。だから、本当に何も意味のあることを追加する感じはしませんでした。そこで、「わかりました、たぶん私が思っていたより良いのかもしれません。」

なぜなら、これがオープンソースのものを取り、それを売ろうとしているものだった私の以前の直感は、Tannerがそれをそれほど好きになるには間違っているかもしれないからです。

そして、さらに重要なことに、彼らがTannerのような人々を彼らのオフィスに連れてきて話をするということは、彼らが私が認めたよりもトレンチにいることを示していました。

私がTannerと話していた理由の一つは、詳しく説明できないドラマですが、とりあえずこれがVercel別れの始まりの間だったとしましょう。これは私の更新が起こった時点でした。

当時、私のメインスポンサーを持っていた時、チャンネルのスポンサーは、私がプロダクションで出荷している、連絡を取って「ねえ、チャンネルをスポンサーしてもらえませんか。そうすれば、あなたの競合他社からお金を取る必要がなく、うまくいく取引ができます」と言ったものでした。

そして、それは多額のお金ではありませんでした。私が持っていた5つのスポンサー全体で、エンジニアとして稼いでいたのとほぼ同じくらい稼いでいました。多くはありませんでした。チームに支払うのにぎりぎり十分でした。そして、私は何も稼いでいませんでした。最初の3年間、YouTubeチャンネルで損失を出していました。

しかし、それは大丈夫でした。仕事がありました。運営していた会社がありました。すべて大丈夫でした。文句を言うためにこれを言っているわけではありません。

物事がどこにあったかの現実チェックのためにこれを言っています。しかし、率直に言うと、一部のスポンサーは支払いについてあまり良くありませんでした。彼らは紛らわしい期待を持っていました。しかし、それは本当に重要ではありませんでした。

重要だったのは、人々がインフルエンサーの意見を買うためにVercelに怒っていたことでした。

今日でも、私がVercelを好きなのは彼らが私にお金を払ったからだと本当に思っている人がたくさんいます。彼らは、それが逆だったことを理解していません。彼らが私にお金を払うのは、私が彼らを好きだからです。

今日まで、私はVercelが今まで支払った唯一のインフルエンサーです。そして、私たちは相互に、このレベルの反発が彼らに、そしてもっと重要なことに私に、それだけの価値がないと決めました。

だから、スポンサー関係を終了しました。それは私がチームを解雇しなければならないことを意味していたでしょう。実質的にフルタイムのエディター、ましてや今のフルタイムのチャンネルマネージャーも持ち続けることはできませんでした。私たちが働いていた少数のブランドからのお金がすべてなければ。

そして、変化の時だと決めました。

2024年9月、TheoはVercelと別れます。皆さんはおそらくもうあの動画を見たでしょう。そうでなければ、見に行ってください。私はあの動画に多くの努力を注ぎ込みました。あの動画を本当に誇りに思っていました。それは私が皆さんに対して、私が何をしていて、それがうまくいかなかったことについて率直になろうとしただけでした。

私は、チャンネルスポンサーが実際にプロダクションで出荷している製品であることを望んでいました。それはうまくいきませんでした。私が本当に好きで使い、率直に言えば絶賛していた、本当に楽しんだものが、もし彼らも私にお金を払ったなら、私は信頼されないという事実は、つまり、私も彼らにお金を払ったなら、私は信頼されないということでした。そして、それは最悪でした。

私が本当に好きで、使用し、出荷し、信頼し、徹底的に実戦テストしたもののみを皆さんに見せることを中心に、私の全スポンサープログラムを構築したという事実が、私の評判を傷つけていました。

そして、今日まで、私はそれについて少し塩辛いでしょう。しかし、それが現実です。明確なスポンサー、良いもの、スポンサー終了を与えなければ、人々の脳は落ちます。これをしなければ、人々は理解しません。

だから、私たちは、私が既に使用してプロダクションで出荷している5つの会社を持つ代わりに、私のオーディエンスに興味を持ったさまざまな異なるブランドからの明確な開始と終了を持つ広告をすべての動画に持つスポンサーモデルに移行しました。

そして、私たちは格段に選り好みが少なくなりました。ランダムなVPN会社や怪しいメンタルヘルスアプリが私のチャンネル全体に貼り付けられることを許可するようなことはありませんが、もはやプロダクションで出荷している会社に限定されることはありませんでした。

私のオーディエンスに関連し、私と私たちが行っていることをよく理解し、これらの広告の小さな1〜2分の窓にピッチを合わせることができるスポンサーが必要でした。

どれだけ多くの人が連絡してきて、どれだけ早く連絡してきたかに驚きました。そして、チャンネルに資金を提供し、この非常に困難な時期に継続させてくれたすべての人に非常に感謝しています。

私は、ここからここまでの間、この変化を補うためにYouTubeチャンネルを自分で資金提供していた個人的な財政の深いところにいました。

新しいスポンサーモデルが、率直に言って、はるかに収益性が高いことが判明したので、今は今まで以上にうまくやっています。だから、古いモデルを使用することで、信じられないほどの金額を、途方もない金額を失っていました。

人々が私を信頼する方法を傷つけていましたし、常に同じ数のものを宣伝していました。うまくいきませんでした。

誰かが、私が明確にする必要がある誤解である良い質問をしました。ある動画で、使用しているソフトウェアの会社からお金を受け取ることは詐欺と見なされるため、そうしないと言ったのではありませんか?

はい。私のチャンネルをスポンサーしてもらう代わりに、私の別の無関係な会社に取引を与えるという交換をしたとすれば、それは詐欺でしょう。

私が彼らの製品について話したためにVercelが私たちに無料ホスティングを与えてくれたとすれば、それは詐欺的でしょう。Vercelが私をスポンサーしていた全期間において、私は特別な割引やアクセスなしに、Vercelにお金を払うユーザーでした。

それは他のスポンサーのほとんどでも同様の場合です。一部の人は、私を好きで、私に試してもらいたいので、スポンサーになる前でも一律アカウントをくれます。ほとんどはそうしません。

私はYouTuberであることよりも、Y Combinatorの会社であることからより多くの割引を得ています。

だから、非常に明確にするために、T3チャットを作る私のビジネスは、私のYouTubeチャンネルである私のビジネスとは何の関係もありません。これらは別々のものです。異なるビジネスだからです。

一方から他方に利益を与えることはできません。さもないと、それらは一つのビジネスとして、一つの課税対象体として一緒にグループ化され、そうすると私はT3チャットを通してエディターに健康保険を与えなければなりません。

これはこのすべてがどのように機能できるかではありません。それは私の税金、財務計画、そして生計を破壊するでしょう。それは実行可能ではなく、とにかくそれをすることは詐欺的でしょう。

チャットにいる私のエディターでさえ、それは変だと同意しています。彼に健康保険を与えないことで詐欺を犯しているわけではありません。

彼は多くの他の人とも働く契約者です。そして、私は彼にばかげた金額を支払っています。少なくともそう思います。彼が支払われているもので快適だと思います。もっとお金に値すると思うなら教えてください、FaZe。喜んであなたに渡します。とにかく最近、あなたにもっと支払うことを計画していました。

しかし、T3チャットがビデオを必要とする時、私がそれを編集します。FaZeはチャンネルで働きます。

要点は、チャンネルで会社について話すのは、彼らがT3チャットに割引を与えたからではありません。これはこのすべてがどのように機能するかではありません。

あなたが私のチャンネルにいるのは、私があなたについて話したいからか、これらのスポンサースポットの一つのために私に連絡したからです。しかし、スポンサースポットの外で出てくる場合、それはもはやあなたが私にお金を払ったからではありません。

ビデオに出るために私にお金を払うことはできません。広告に出るために私にお金を払うことしかできません。そして、その場合でさえ、それをさせるために十分に私があなたを好きでなければなりません。なぜなら、チャンネルをスポンサーする人について本当に選り好みできる特権的な立場にあるほど多くの引き合いがあるからです。

この変化の後に私に連絡してきた最初の2つのスポンサーは、Infinite RedとFrontend Mastersでした。なぜなら、両方とも実質的に私が行っていることを理解し、機会について興奮していた人々によって運営されていたからです。

これら2つのグループは私たちが生き延びることを可能にし、最終的にBenをフルタイムでここに連れてくるのに十分なお金を稼ぐことを可能にしました。彼は私が今撮影している間、私のキッチンにいます。私たちの成功を見つけるために不可欠です。

そして、率直に言って、彼らは結果として本当に良い取引を得ました。今請求できるものの5分の1未満を、これらの価格設定方法をまだ知らなかったので、これらの人たちに請求しました。

しかし、すぐに別のブランドが続きました。Convexが私に連絡してきました。

Convexとの本格的な関わりの始まり

もしConvexがTannerとのチャットの前に私に連絡してきていたら、正直に言うと、おそらく無視していたでしょう。私はこの時点まで、ConvexをクローズドソーススタートアップであるオールインワンのRails代替と考えていました。

しかし、Tannerが彼らを本当に真剣に受け止めていると私に言い、サーバーとデータベースを必要とする製品を構築しているなら彼らを使うだろうと言ったので、「なるほど、確かに、なぜダメ?私たちはもっとスポンサーが必要でした。もっとスペースを埋める必要がありました。

私が好きな十分な人がConvexについて良いことを言ったので、彼らを推薦することが必ずしも私のオーディエンスにとって悪いことではないと感じなくなりました。

私は本当に、将来彼らを失敗させるテクノロジーで人々をセットアップしたくありませんでした。私が推薦したために誰かが何かを選び、結果として悪い状況に陥るという考えは、今日でも私を病気にさせます。

私が行った推薦が誰か他の人を台無しにするかもしれないということが、夜も眠れなくさせます。それをとても嫌います。

しかし、Convexが単にTannerの嗅覚テストに合格したことで、チャンネルに載せるのに十分良いと感じました。特に、これがスポンサー部分であるという明確な区別に包まれて再び行うのであれば。

ブランドが私をスポンサーする時に私が行うもう一つのことは、彼らのマーケティング、SDK、ブランディング、そして私のオーディエンスが製品を好きになるために必要な他のすべてに膨大な時間を費やすことです。

私のオーディエンスが変換しない会社に広告を売りたくありません。人々が彼らのウェブサイトに現れて、実際に変換しないブランドが多くの注目を集めるのを手伝いたくありません。なぜなら、サイトが実際に彼らにどこに行くべきかを示さなかったり、手伝ったりしないか、何らかの方法で失敗するからです。

だから、率直に言って、ほとんどのスポンサー取引に気持ち悪いほどの無料コンサルティング時間を投入しています。私は任意のブランドと、彼らのオンボーディング、ホームページのコピー、YouTubeとマーケティングのより良い理解、これらすべての異なることを手伝って、あまりにも多くの日数を費やしています。

私がこれまで働いたどのブランドよりも、Convexをかなり多く手伝いました。彼らはそれに非常に受容的で、これらの会話を通して、Convexチームだけでなく、Convex製品の価値も非常に早く見え始めました。

私はまた、この頃、彼らがConvexのすべてを完全にオープンソース化したことを学びました。コードがそこにあるというだけのオープンソースではありません。

CEO のJamieは、それが常にデプロイ可能であることを確実にするために個人的に努力し、人々が実際にそれを使用できるように、楽しみのためにRailwayでConvexをデプロイしようとして週末を過ごします。非常にクールです。

これらすべてが、私の信念を本当に築き上げ始めました。そして、Jamieがチャットで言ったように、私はTheoを諦めませんでした。彼が近くで見れば、Convexを愛するだろうと本当に思っていました。

そして、彼は私が近くで見るために必要なすべての理由を与えてくれました。スポンサーシップは最終的に、Convexをより詳しく見るためのゲートウェイになりました。なぜなら、再び、あなたが私のチャンネルをスポンサーする時、あなたは私に言うことを与えません。

あなたが私のチャンネルをスポンサーする時、あなたはあなたのものがなぜ興味深いかについて私のオーディエンスを説得するために最善を尽くす時間空間にお金を払っています。私は彼らに嘘をつきません。

真実でないことを彼らに言いませんが、あなたのクソなコピーは取りません。私は私の動画で他のことについて話すのと同じ方法で、あなたの製品についてリフをします。

そして、誰かに正直に推薦できるほどあなたのものを好きでなければ、おそらくスポンサーを受けません。

だから、Convexと私は多くのやり取りをしました。私は彼らを物事でたくさん手伝いました。私は彼らにホームページのコピーを変更するよう説得しました。

あなたのReactアプリのもう半分、またはあなたのReactオフィスの欠けている半分でした。そのようなものから、それがあなたのアプリケーションでReactの下のすべてであることを本当に強調するものに。

そして、私はそれをもっと触り始めました。大きなことがクリックしました。私がオールインした瞬間は、私にとって非常に特定的でした。

すべてがクリックした瞬間は、Convexアプリがどのように構造化されているかについて何かを理解した時でした。

Convexアプリの構造における重要な発見

Convexアプリには、このconvexフォルダがあります。このconvexフォルダには、すべてのデータ型を定義するスキーマから、認証を処理するAuth設定、ファイルアップロードがある場合はそれ、アプリケーションにアクセスするために使用するすべてのものまで、すべてが含まれています。

だから、Convexからデータを取得するために、何らかの文字列を書いてDBを叩くだけではありません。私のスキーマのすべてが公開されているわけではありません。これは単なるデータベース定義です。

それを公開するために、私は別のファイルを作成し、データベースを叩いてデータを返すクエリを公開しなければなりません。

私のインフラの動作方法の全体がこのフォルダであることを理解した時、Convexは私が生涯探し続けていたTerraformのような何かに対する欠けている代替であることを理解しました。

Convexが唯一の真のinfra as codeプラットフォームであることがクリックしました。他のすべての人は、infra as codeのこの概念を、ランダムで不適切にフォーマットされた設定ファイルに接着しようとしています。

実際に、ダッシュボードで時間を必要とせず、このコードを取って他の誰かに渡し、設定なしで彼らのConvexアカウントですぐにセットアップできるものを持っている人は誰もいませんでした。

それは私にとって巨大な「なんてこった、光が見える」瞬間でした。特に、この同じ頃、AIアプリビルダーが注目を集めていたからです。

言及すべきだった初期のスポンサーのもう一つは、Stack Blitzという小さな会社でした。Stack BlitzのEricが、スポンサーの件について話すために私のアパートにやってきました。そして、私は常にStack Blitz、ブラウザ内エディターを愛していました。そして、Ericは永遠に友人でした。彼は私に注目した最初の人の一人でした。そして、率直に言って、Ericは私のヒーローです。

私はその人をとても愛しています。Stack Blitzを愛していました。そして、ブラウザ内コードエディターがどれほどクールかを人々に伝えるためにできることすべてをすることにとても興奮していました。

しかし、一緒に過ごす時間の終わり近くで、彼は言いました、「ところで、これを見るべきだと思います。私たちは新しいものをドロップしようとしています。」

私はStackBlitz以外で最初の人の一人でした。実際、Bolt.newを試すことができた最初の人だったかもしれません。

そして、それは本当にクールでした。それがどれだけうまくいき、どこまで行くかは全く分かりませんでしたが、それは任意のフレームワークを使用できるAIアプリビルダーでした。そして、「ああ、くそ、ここでの可能性が見える。AstroやVue、Svelteやその他何でも初めて使用できるのは本当にクール」と思いました。

そして、彼は広告をBoltについてにしたかったのです。私はStack Blitzについての広告にしたかったので躊躇しました。なぜなら、Stack Blitzを知っていて愛していたからです。彼は本当にBoltがそれらのいくつかの焦点であるべきだと思っていました。だから、いくつかのためにそれをしました。

それは確実にローンチを少し後押しするのに役立ちましたが、Boltは独自の生命を取り、今では数百万ドルの収益を上げている巨大なスタートアップです。破産の瀬戸際にあったStack Blitzを救いました。私がスポンサーしている時は、そのことさえ知りませんでした。彼らが大丈夫だと思っていました。

そうではありませんでした。Boltが彼らを救いました。今、彼らは殺しています。そして、今、私は投資家でもあります。なぜなら、彼らが行っていることにとても興奮していたからです。

私がこれすべてを持ち出すのは、Boltやその実装ではなく、このアプリのカテゴリ全体で問題を見始めたからです。

今日でも、Lovable、Bolt、またはV0にあなたのアプリに認証を追加するよう頼むと、成功する確率は5分の1です。75%以上の時間で、彼らは認証のセットアップに失敗するでしょう。

ファイルアップロードを追加するよう頼むと、15の異なるサービスの1つを選び、あなたがサインアップして、APIキーを取得して、それを貼り付けて、最善を期待し、それでも失敗することを要求するでしょう。

これらのAIアプリビルダーは、UIと一部のバックエンド機能をスキャフォールディングするのは本当に得意でした。

しかし、率直に言って、これらのフロントエンドツールがどれほど良かったかのために、彼らはそれが得意でした。ReactはAIがアプリを生成することを本当に簡単にしました。なぜなら、AIはテキスト生成を本当によく扱うことができるからです。そして、Reactはすべての関心事を1つの場所にまとめることをかなりよく行います。

だから、AIはテキストを読み、何が欠けているかを把握し、その1つのコンポーネントにそれを追加することができます。物を見つけるために多くの異なるファイルをチェックする必要がありません。

最終的に、それが得意になり、それがさらに良くなりました。しかし、ReactはAIにとって本当に良い構築ブロックでした。

そして、ここが最もスパイシーな意見が来るところです。ConvexはあなたのReactアプリの欠けている半分だけではありません。それはあなたのバックエンドのためのReactです。すべてがリアクティブな意味ではありませんが、そうです。

Convexは、あなたのアプリケーションを構築するための代替プリミティブセットです。Reactは、私たちのプリミティブが間違っていると言ったので、新しいものを作るつもりです。アプリをmodel view controllerに分割する代わりに、正しいIDで正しいものを見つけようとする奇妙なAPIでDOMを横断する代わりに、UIで示すものから完全に分離して状態とデータ管理を書く代わりに、異なるプリミティブセットを作ったらどうでしょうか?

Reactは、ブラウザで行うことの抽象化ですが、すべてを奪ったり、ピースを組み立てる能力を奪う意味での抽象化ではありません。

使用できる別のプリミティブセットという意味での抽象化です。新しいものを追加するスーパーセットであるTypeScriptのようなものではありません。それは代替です。ウェブアプリケーションを構築する方法について考える異なる方法です。

そして、これらの異なるプリミティブには独自の利点と、独自の副作用もありますが、それらはほとんどのものを構築するためにはるかに良いことが判明した代替セットです。それがReactがそれほどうまくいった理由です。

アプリを構築するベースプリミティブとしてのコンポーネントとフックのこのアイデアは、以前に従事していたカオスよりもほとんどのものを構築するためにはるかに良いことが判明しました。Convexは同じことをしました。

しかし、違いがありました。ReactはあなたのAPIを叩くものです。ConvexはAPIです。Reactは、それの一部に使用され、その後人々がなぜそれが有用かを見て、あなたの全体のアプリケーションを乗っ取るまで、段階的にあなたのコードベースに感染する可能性がありました。

Convexはあなたのアプリケーション全体です。

Reactは、段階的に採用でき、一度に一つずつ問題を解決することができ、オールインするまでという事実のために成功することができました。Convexには同じ利点がありませんでした。

しかし、このAIアプリビルダーピースに戻りたいと思います。なぜなら、これが私の意見では、彼らにとって本当に物事を変えたからです。

私が言及したように、Reactはより段階的に採用でき、その後あなたはそれをすべてに使用するでしょう。Convexには同じ利点がありませんでした。

しかし、Convexが持っていたのは、私のアプリケーションを組み立てるためのより良いプリミティブセットでした。そして、これらのプリミティブはすべて、ただのコードでした。Convexが行うことのどれも、ダッシュボードに行ったり、ランダムなAPIを叩いたり、CLIを実行したりすることを要求しません。あなたはただコードを書き、それがそれを行います。

私はコードを書くのがかなり得意ですが、コードを書くのが得意な他の何かを知っていますか?LLMです。

正しいIAMロールを設定するため、またはデータベースが正しくセットアップされていることを確実にするために、ダッシュボードをナビゲートするのが本当に悪いのは何ですか?LLMです。

特に多くの異なる場所に存在する時、状態を管理するのが本当に悪いのは何ですか?私たち開発者です。

それがReactがとてもクールな理由の一部です。それは状態について考える方法を変え、それがあなたのアプリを通してただパイプされるようにしているからです。そして、あなたが書いているほとんどの時間、あなたは状態について考えてさえいません。あなたはそれがどこに行くかについて考えているだけです。

Convexは実質的に同じことをしています。現在のデータベースの形状が何であるかを把握するためにMCPを実行してAPIをクエリする必要がありません。私はただコードファイルを見ます。

データベースを異なって形作りたい場合、私はファイルを変更します。Convexでのほとんどすべては、そのConvexフォルダ内のファイルを変更するだけで行うことができます。

これは、第一に、私が非常に幸せな関数プログラマーであることを意味しました。なぜなら、途中のすべてのステップで状態について考えていないからです。

しかし、もっと重要なことに、AIもConvexで本当に良くなる可能性があることを意味していました。なぜなら、データベースを変更するためにMCPは必要ないからです。アプリケーションの状態が何であったかを把握するために奇妙なツールコールやインターネットでブラウジングする方法は必要ないからです。それは文字通りinfraとして、文字通りただのコードです。

そして、最良の部分は、それがクレイジーな新しい構文やXMLのろくでもない改造ではないことです。それはただのTypeScriptです。

「それはただのTypeScript」の深さは、私が言葉で単純に置くことができるところを超えています。私たちは一緒にそのすべてを見ていきます。心配しないでください。長いビデオになりそうです。もう分かります。

しかし、それが私にクリックした時、Jamieにヒットアップしなければなりませんでした。チャットにいるのが見えます、Jamie。

初めて私たちのDMを共有しても大丈夫ですか?人々とプライベートに共有したことはありますが、私にクリックしたDMを人々に見せたいと思います。

今、私たちは今年の3月にいます。「Convexの上に構築されたAIアプリビルダーを行うことについて多く考えましたか?私たちには様々なことを行っている4つの会社があります。」彼らはこれらすべての他の会社と、AIアプリビルダーのような様々なことを行って働いていました。

「私たちは独自のものを行うことについて議論しましたが、それを実現するのにどれだけの作業が必要かについて恐れています。おそらく私たちはそれについて間違っています。」

彼はそれについて話しています。「あなたは正しいかもしれません。私は別のメッセージを送りません。10分後、バックエンド側ではなく、新しい発明のあれこれ。」私は言いました、「Boltの多くはオープンソースです。」真実です。「私たちは内部でそれを分裂させました。Bolt DIY。なぜ私たちはただそれで走らなかったのか?」良いポイント。「たぶん私たちはそれをするでしょう。くそ、私たちはそれをするべきです。」

そして、それほど後でなく、私たちはChefを得ました。部分的にBoltによって動力を与えられたAIアプリビルダーで、Convexを使用して一からアプリを構築することを可能にします。

そして、他のすべてのAIアプリビルダーとは異なり、それが作るものはとてもきれいではありません。とても派手で興奮させるものではありません。しかし、他のすべてのアプリビルダーとは異なり、それらは実際に動作します。

私は昨夜友人にこれをデモしていて、私のお気に入り、またのSlackクローンをしました。

私は彼らのデフォルトプロンプトを使用しました。なぜなら、それのためのデフォルトプロンプトはかなり良いからです。「次の機能を持つSlackに似たアプリを構築してください。左側にチャンネルがあり、作成ボタンがあり、メッセージパネルがあります。」これらすべてのピース、アイデアが分かります。

そして、それは作成されました。もう少しスペースを与えるためにコマンドマイナスします。これが私たちのために作成されたアプリです。別のチャンネルを素早く作ります。ここに飛び込みます。「Sup nerds.」別のプレビューを追加します。匿名でサインインします。すべてが動作する認証があることを覚えておいてください。非常に便利です。

別のメッセージを送ります。これでそれを送ります。他のチャットで自動的に現れるのが見えるでしょう。クール。素晴らしい。

しかし、彼らは私が考えてもいなかった何かを追加しました。そして、これが私にとって「なんてこった、これは未来だ」瞬間でした。これがすべてが終わった瞬間でした。そして、それがあなたに私にとって持ったのと同じ効果を持つことを願います。

データベースタブに行きます。これは彼らのダッシュボードの埋め込みバージョンです。そして、埋め込みと言うのは、それが文字通り彼らのダッシュボードだからです。

これが私たちのデータです。メッセージに飛び込みましょう。ここで送ったメッセージは「別のメッセージ」です。これを「購読を忘れないでください」に変更します。

今、プレビューに戻ります。それは既に変更されました。デシンクはありません。消える問題の量、私が実現していなかった精神的オーバーヘッドの量、すべてが私のユーザーにとって良い体験になるために十分に同期されることを確実にするために投入していた、それを試した瞬間に消失しました。

そして、最も困難な部分は、開発者としての私たちにとって、これはクレイジーです。しかし、普通の人にとって、これはまさに彼らがそれが動作することを期待する方法です。

コードを何年も書いていない普通の人は、これら2つのタブがそれほど異なるべきだとは思いません。

一つはあなたのデータベース、一つはコードです。ここで何かを変更するとUIがすぐに変更されるのはなぜでしょうか?しかし、ここで何かを変更するとリフレッシュが必要です。普通の人にとって意味をなしません。

私たちはすべてこれに条件づけられており、私たちは間違っていました。これがアプリケーションデータに対してどのように動作すべきかです。今、私は夢中です。

これが私にとってのマジックアハでした。そして、率直に言って、それはデモするのをはるかに簡単にしました。突然、Convexを人々に見せることについてずっと自信を持つようになりました。なぜなら、そのデモはとても殺人的だからです。

とても派手だからというだけでなく、なぜなら、それは本当にクールなデモだからです。そして、それははるかに遠くまで行きます。T3チャットの開発環境でlocalhostを立ち上げると。

これが、Nextを使用し、Convexを使用している私のT3チャット開発環境です。言及したように何度も、Nextを使用しています。それは私のろくでもない半フォークです。

私はまた、T3チャット用の私の開発インスタンスであるConvexに飛び込んでいます。だから、これが私のT3チャットです。これが私のConvexインスタンスです。これがオレンジについてのスレッド情報です。データに飛び込みましょう。オレンジについてのスレッド情報。

それをグレープに変更します。すぐに変更されます。ビューを分割します。同時に両方を見ることができます。リンゴに変更します。Enterを押すとすぐに変更されます。

これでとても多くの問題が消えます。クレイジーです。データが何かをする前に最新であることを確実にすることに費やした人生の時間の量は、それについてどれだけ考えてもいなかったかです。

そして、再び、私が続けて行う比較はReactとです。なぜなら、その点で私には非常に似ているように感じるからです。

皆さんのほとんどは、要素がページにあるかどうかを更新する前にチェックする痛みを知らないほど若いです。クリック時にボタンの状態を変更したい場合、ボタンがそこにあるかどうかを知る必要があります。

だから、IDを使用してそれを見つけようとします。そして、それが存在すれば、私はそれを更新します。そうでなければ、おそらくパニックするか投げます。

jQueryの時代に、私たちがすべて、次のことをする前に物事が正しいことを確実にするために費やした時間の量は、私にウェブ開発を好きでなくさせました。

私のキャリアのほとんどでウェブ開発を本当に好きではありませんでした。なぜなら、それの多くが、次のことをする前に物事が正しいことを確実にすることに費やされていたからです。

Reactはそのすべてを取り除きました。デフォルト状態が非常に明確で、何かをしているなら、それをしている要素が存在することを意味しました。ボタンのオンクリックは、ボタンが存在せずには存在できません。そして、関数はそのコンポーネントのコンテキスト内で定義されます。

それはすべてを理解し、構成し、拡張し、その間のすべてをずっと簡単にしました。それはウェブでの開発にとって人生をずっと良くしました。

Convexは私のバックエンドに対してそれを私にしてくれました。そして、その日を見るとは思いませんでした。私がこれほど多くを私のためにしてくれるプラットフォームを選ぶとは思いませんでした。

私が理解するのは、それがFirebaseの代替のようなものではないということです。すべてをあなたのために処理し、データベースに直接ぶつける最悪のSDKを与えるオールインワンソリューションです。

Convexは、あなたのアプリケーションを構築するための異なるセット、より良いプリミティブです。ReactがIDでget elementを置き換えたのと同じ方法で、コンポーネントで。ConvexはデータベースマイグレーションとIAMロールをTypeScriptに置き換えます。

それがクリックした時、魔法的です。

明らかに、ChefはConvexにとって非常によくやっています。人々はそれを試し、魔法を発見し、それを使用しています。しかし、私の旅の別の部分があり、それをカバーすることが重要だと思います。

これはすべて、私がちょうど言ったチャンクの一部です。これが起こり始めたのは2025年3月だったと言うでしょう。確実に、これは「Theoが光を見る」瞬間です。

しかし、まだ話していない、その間に起こった別の重要なことがありました。

T3 Chatの構築とローカルファーストの挑戦

私はT3 Chatを作り、以前にしたことがないことを本当にしたかったのです。T3 Chatまで、私が構築したほとんどのものは、サーバーによって重く駆動されていました。

それが私がそのようなビッグサーバーコンポーネントの人だった理由です。なぜなら、再び、私の目標は、クライアントが間違った状態になったり、何かがうまくいかない可能性を高くする間違った場所により多くの状態が存在するこれらの潜在的なケースを減らすことだからです。

私の意見では、あなたのアプリがサーバーとサーバー上のデータによってより駆動されるほど、奇妙なことにぶつかる可能性は低くなります。そして、Convexは幸いに同意しています。

私は彼が以前にこれについて何かを言ったのを見ました。「私たちはTheoに同意します。ConvexはバックエンドのためのReactです。」そう、一方の側にデータがあり、もう一方の側にユーザー体験があるパイプとしてのあなたのアプリケーションの、この関数理想の考え。

途中のすべてのステップに状態を詰め込む代わりに、その方法について考えることができるほど、あなたの体験はより信頼でき、これらのコードベースで作業することは常により簡単になります。

私は永遠にこの丘で死ぬでしょう、そして彼らがこの点で私と一致していることを非常に感謝しています。

とはいえ、私は本当にT3 Chatをめちゃくちゃ速くしたかったのです。明らかに、ローカルファーストは常にパフォーマンスの点で一般的にサーバー駆動より良いでしょう。

サイトを移動している時、データをサーバーに待つ必要がないことは、サーバーを待つより常に速いでしょう。明らかに、コードを本当に悪く書いたら、コードを本当に悪く書いたのです。

しかし、良いデザインの極端では、ローカルファーストはサーバー駆動より良いでしょう。私はT3 Chatを今まで最高にしたかったのです。

そして、私たちは激しく戦いました。そして、その一部は、私が自分のローカルファースト同期エンジンを構築したことでした。詳細にはあまり入りません。なぜなら、私は多くの異なる時にそれを持っているからです。

ローカルファースト同期エンジンを構築して私が自分を地獄に投げ込んだ地獄をより良く理解したいなら、データベースマイグレーションについての私の他のビデオを見に行ってください。

TLDRは、Dexieは本当に良いです。それが構築されているAPI、IndexedDBは完全なゴミです。同期エンジンプラスローカルファーストスペースのすべての人は、無知か嘘つきです。

ああ、私は地獄に行ったり来たりしてきました。特定の人を呼び出すつもりはありません。なぜなら、彼らのせいではないからです。彼らが言っているすべては真実であるべきです。ただ、そうではないのです。

私はこれすべてを機能させるために本当に懸命に努力しました。そして、他の選択肢を探ることに多くの努力を注ぎました。私たちはZeroをデプロイしようとする最初の会社の一つでした。

私たちはTiny BaseからLegend State、その間の多くの他のソリューションまで、すべてを深く調べました。そして、何をしても、現実では何も機能しませんでした。

現実は、ローカルファーストがすべての人にとって異なることを意味し、あなたがそれを望む理由は大幅に変わるということです。したがって、一つのサイズがすべてのソリューションに機能することはできません。

同じ同期とローカルファーストソリューションがFigmaとLinearの両方で機能できると正直に思うなら、一つのビデオで解決できない両方の製品のいくつかの基本的な誤解があります。

これら2つの製品、両方ともローカルファーストと同期を行う製品が、同じプリミティブを使用して類似のものを構築できる可能性のある世界はありません。それは明らかに真実です。

そして、何らかの理由で、すべてのローカルファーストの人々は彼らがそれをできると思っているようです。Convexはそうしません。

そして、私はローカルファーストコミュニティとの私の会話とConvexとの私の会話との間で、具体的な違いを感じました。

彼らはローカルファーストの状態について、そして特に彼らがそれを全くサポートしていないことについて、ずっと現実的でした。彼らは将来それを理解しようとすることに興味を表明しましたが、それがそのような不条理なカオス的なウサギの穴であることを知っていたので、それをしないことを選びました。

そして、それは正しい呼び出しでした。なぜなら、ローカルファーストの構築はかなりクソ吸うからです。

この時点で、私は多くの異なる選択肢を検討していました。私は、私たちのためにシンクエンジンを構築するために創設者を引き抜きたかったので、スタートアップを購入することをほぼ考えました。なぜなら、それを自分たちで維持することにとてもうんざりしていたからです。

私はConvexを含むすべての選択肢を探り、それらのどれも私たちが必要とすることをしなかったと結論づけました。

しかし、最後のラップともう一度それを自分でしようとする最後の試みの後、もし私が2つのピースを取り除く意思があれば、具体的に、ローカルファーストピースを手放す意思があり、トークン化されたストリームがDBを通るべきだというアイデアを手放す意思があれば、多くの異なる同期エンジンが突然私たちの製品にとって実行可能になるという事実を受け入れました。

ここで私が意味するのは、T3 Chatでメッセージを生成する時です。使ってみます。速いです。「Reactについての10の詩を書いて」。これらのトークンがどれだけ速く来ているかを見てください?そして、それらは個々の文字で来ています。まあ、準備ができた時の4から10の間の文字のグループです。

だから、もし私が一つの真実の源、私のサーバーから私のユーザーへの一つのパイプが欲しいなら、理想は、この生成がそれらのパイプを通ることでしょう。理想的な世界では、ユーザーはサーバーに送り、レスポンスを生成し、明らかに生成しているもののコンテキストで。

サーバーは生成される各トークンをデータベースに送り、それからユーザーのチャットUIに送信するでしょう。これが私の理想でしょう。サーバーにレスポンスを生成するよう伝えます。これが生成されます、1から100まで数えるように言います。そして、これは1を送り、それから2を送り、それから3を送り、それから4を送る、等々。

そして、それらの一つが来るたびに、UIでアプリで見ることができるように送信するでしょう。

問題は、それが同期エンジンの動作方法ではないということです。同期エンジンであるデータベースの内容を更新する時、何が変更されたかを送信しません。1を送ってから、それに2を追加するように言いません。

それは1を送り、それから1、2を送り、それから1、2、3を送る、等々。結果として、ばかげた量のデータを送信します。

同期エンジンは、各トークンを個別に保存しない限り、この問題には機能しません。私たちは今、月に最低でも1兆トークンを経由しています。これらのもののいずれかに1兆のクソ行を保存するつもりはありません。

あなたの行がメッセージであるなら、そうあるべきですが、これは機能しません。そして、それは私の心を壊します。

私はこれがとてもひどく機能することを望んでいましたが、それはできません。多くの同期エンジン会社は、彼らがそれをできると言うでしょう。彼らはあなたに嘘をついており、あなたは走るべきです。

私はこれらの会社から、AIが実際にどのように動作するかについて、「まあ、それが終わった時を知るためにOpen AIを引っ張ることができる」から「まあ、API はとにかくパラグラフを送ってくるのではないか?なぜそれらを保存しないのか?」まで、とてもばかげたことをたくさん聞きました。

それらのどれも現実ではありません。あなたが理解していないことについてなぜそんなに自信を持って話すのですか?ああ、あなたがローカルファースト同期エンジンを構築するからです。それは理にかなっています。

ローカルファーストについての私の咆哮が近い将来来ます。私がここで作ろうとしているポイントは、これが私の理想であり、これが現実の動作方法ではないということです。

Convexにこれを持ち上げた時、Jamieは非常に早く答えました、「ああ、そう、それは吸いますね?私たちは構築したいくつかのソリューションを持っていますが、それらはちょっと時代遅れです。これは1年前にこれについて書いた記事です。私たちはこれを少し見直すつもりです。」

彼らと話し、彼らがしていることを見た後、私はインスパイアされ、自分で実現しました。

ここで私が望んでいたもの、各トークンが準備できた時にこれらのメッセージを表示すること、それは楽観的更新です。

実際に重要なのは、全体が終了した時、1 2 3 4から100まで、これすべてがデータベースに行き、ユーザーに送信できることです。しかし、私は彼らにもっと見せたいのです。

もし私が以前に説明していたもの、トークン化されたストリームもユーザーに送り返し、これを私が持っているなら見せる、持っていないなら待つ楽観的更新として扱うなら。

これがクリックした時、人生は大幅に簡単になりました。そして、これは、Convexが会話を持ち、彼ら自身の推薦とソリューションを持つのに十分気づいていたためにのみ、私にクリックしました。

そして、これが彼らの例で行っていた方法です。完了したメッセージがDBに行き、それからユーザーに、部分的なメッセージが大部分のLLM生成のもので行うようにサーバー送信イベントで単にストリーミングされるように、この方法で分割した後。

人生ははるかに簡単になりました。

そして、私が後で理解したのは、ここのこのセクション、この楽観的更新レイヤーを取って、それをRedisパブで包み、この部分を再開可能にできることです。

だから、私たちのチャットストリーム再開可能性、私の意見ではT3 Chatで最もクールな機能の一つ、それを見せるために遅いモデルをします。これにKimmy K2でReactについての10の詩を書くよう伝えます。

このモデルはちょっと遅いので、これには時間がかかりますが、来ています。各トークンが来る時にそれを伝えることができます。私は他のブラウザを開くつもりです。

そして、ここにConvexの使用なしでストリーミングされています。Convexはこの部分を手伝っていません。なぜなら、これは楽観的更新だからです。

Convexは T3 Chatに「これがあなたのスレッドです。これがあなたのメッセージです。私たちが知る限りのメッセージの内容です」と伝えますが、ストリームは今Convexに保存されていません。

Convexはこれを空のメッセージだと思っていますが、私がRedisを通してPubSubを通して行っている復元IDを与えました。これはすべての世界の最高であり、T3 Chatを維持することで私たちにとって人生をずっと良くしました。

これは、Convexが私たちに機能を与えるからではありません。これは、Convexが正しいからです。彼らはこれらのことについて考え、問題を解決するための正しい考え方を与えてくれます。

そして、私がここでこのすべての詳細に入る理由は、Convexのプリミティブとして何が素晴らしいかを理解した別の瞬間だったからです。なぜなら、Convexのプリミティブは、更新をデータベースに送信するこの部分を本当によく処理するからです。

彼らは、UIが常にデータベースに保持されているものを正確に知ることを確実にするこの部分をさらによく処理します。

彼らはこの部分では何もしませんが、する必要がありません。この部分は私が望む方法で自分でできます。それがConvexの魔法です。それはほとんどのもののためのより良いプリミティブセットです。

私がConvexを使用していない方法を示すことで、どれだけConvexを愛しているかを見せているのはちょっと面白いです。しかし、このプリミティブセットがどれほど強力かを示すと思います。

そして、この時点で私は完全に夢中です。これはすべて、この期間にわたってクリックしています。私は、既存の同期エンジンを機能させるために最後の一回の試みをします。

しかし、私は実際に私たちのDIY同期エンジンを理解している会社で唯一の人なので、私のチーム全体を阻害していることを理解します。他の誰も、データレイヤーがどのように動作するかを本当に変更したり、データベースの構造を変更したり、新しいものを追加したり、同期を修正したり、他の何かをしたりできません。

だから、TheoはConvexの周りでT3 Chat全体を書き直します。

皆さんは、beta3 chatが物だった、T3 chatベータを覚えていますか?それはこの書き換えの初期バージョンでした。そして、男、私は速く恋に落ちました。

ところで、これすべてについて、Convexチームに大きな感謝を。彼らは、共有Slackチャンネルを作成しました。彼らは私たちのコードベースにいて、私たちがぶつかった問題に注意を払い、それらを修正していました。

おそらく、最低10回、私は彼らに、彼らのものがクソだと自信を持って言いました。彼らのキャッシングが壊れている、彼らの認証が壊れている、これらすべてのことを言いました。

10回すべて、私は間違っていました。彼らのものはとてもよく動作しました。

そして、私が自信を持ってそのものが間違っていると言うたびに、彼らは4倍チェックし、私が正しいと仮定し、それから彼らのものが正しく、私たちが何か他のもの、私が間違ったこと、または私たちの深さの一人が間違ったこと、または私たちのソリューションパイプラインの何か他のものが機能していないことが判明します。

私がConvexを問題と呼び出そうとした時、Convexが問題だった一度もありませんでした。

彼らは彼らのクソを知っています。そして、ところで、そのキャッシュレイヤーは信じられないほどです。私たちのクエリの98%、それ以上でないなら、キャッシュにヒットしています。だから、データベースから全く読んでいません。とても良いです。

これについては少し入りますが、これが私がすべてにオールインし、今私が構築するTypeScriptであるすべてにConvexを使用する時です。

ここで私がしたい2つの特定のことがあります。この動画の最後の2つの大きなピースのように。一つは、私が愛するすべての小さなことです。そして、もう一つは、Convexを使用すべきでない時はいつですか?

そして、私が本当にしたい3つ目もあります。それは私を苛立たせる小さなことです。いつものように、私が好きでないことがあるからです。そして、これはスポンサー動画ではありません。つまり、それはスポンサーされていますが、他の誰かによって。

Convexは、これのどれにもお金を払っていません。彼らは、私が物事を説明する方法について注意深くあるようにいかなる時点でも私に言っていません。彼らは気にしません。

私が彼らをロースト する時、彼らは好きです。なぜなら、彼らがすることがより多くあるからです。だから、私を苛立たせるすべてのことについて話しますが、これが最初に重要なピースだと思います。

私が人々に、すべてにConvexを使用しろと言っているとは思ってほしくありません。そうではありません。

とはいえ、あなたのデータがTypescriptで書かれたバックエンドとクライアントでのみ使用される場合、他の何かを使用することを正当化するのは本当に困難です。それが私の正直な意見です。

あなたのデータベースが、あなたのアプリケーションでのみ、そしてあなたのバックエンドでのみ排他的に使用されるものであり、これら2つのものが両方ともTypescriptである場合、ほぼ確実にConvexを使用すべきです。

しかし、それが変わる瞬間、Goで別のバックエンドが必要な場合、またはRustで書かれたCLIが必要な場合、またはデータチームが分析とクソを実行するために直接アクセスが必要な場合、これらの時点で、Convexはほぼ即座に意味をなさなくなります。

それを機能させる方法があり、彼らはそれらすべてについてあなたに教えるでしょう。しかし、私は、気にしないでくれと言うつもりです。

しかし、私はとにかく、これらのケースのどれも好きではありません。Goで別のバックエンドは、パフォーマンスがボトルネックになる奇妙な特定のものがあり、Goが必要でない限り、おそらく起こる必要がありません。そして、その時は、GoでそれらのものをGo and call them from Typescript。おそらく実際のケースではありません。

しかし、すべてをGoで書くことを主張するバックエンドチームがある場合、あなたは最初からConvexを見ていませんでした。現実的になりましょう。彼らを見ないでください。彼らはあなたのためではありません。そして、それは大丈夫です。

あなたはTypescriptではないCLIと物事を構築しています。あなたが何をしているかを見たいと思いますが、データベースが全く必要ない可能性が高いです。

そして、必要だとしても、おそらくそれにConvexを望まないでしょう。しかし、この下のものは重要です。

あなたのデータベースが複数の異なるアプリケーション、複数の異なるバックエンド、複数の異なるものによってアクセスされている場合、明確にするために同じデータベース、Convexは多くの意味をなしません。なぜなら、私のデータベースとその定義とすべて、それらは私のアプリコードに住んでいるからです。

T3 Chatコードベースのデータベースは、ここにあります。これは、T3 Chatコードベースの私たちの実際のスキーマです。まだbetter chat nextという名前の1つのpackage JSONがあります。なぜなら、それが中間名だったからです。

これには、すべてのフロントエンドコードがあります。Next.jsがあります。これらすべてのものがあり、Convexと、データベースを機能させるために必要なすべてのConvexのものがあります。それはすべて1つのコードベース、1つのプロジェクトです。

私たちが独自の技術スタックと独自のすべてを使用する別のバックエンドチームを持ち、彼らがこのデータベースへのアクセスを望み、それに対していくらかのコントロールを持ちたい場合、いや、Convexと良い体験ではありません。それが全くそのためのものではありません。

これらのものが密接に結合されている時、それらが通常そうであるのは現実的ですが、それがうまく機能する時です。

しかし、このケースは私が多くの人が心配しているのを見るものなので、私はそれに飛び込み、もし本当にこれが必要なら、他のチームと他のバックエンドが同時に同じデータベースを使用する必要があるなら、Convexは意味をなさないと言いたいと思います。

今、失礼なコメントを残そうとしていた人々が満足したことを願って、私は彼らを苛立たせるものを言うつもりです。うまくいけば、彼らは既に動画を離れています。私たちが十分に雑草の中にいて、彼らが既に去ったことを指を交わします。

これをクソするな。あなたのデータチームが分析とクソを実行するためにデータベースへのアクセスが必要な場合、彼らに異なるクソデータベースを与えてください。

Convexで行っていることを他の場所にファイアホースアウトするだけです。ここに私たちが持っているものがある場合、あなたの分析チームまたはあなたのデータチームは他の何かが必要です。

クソクリックハウスやAxiomのようなものを使用したり、Post Hogを直接使用したりするだけです。誰が気にしますか?すべてのデータをそこに送るだけです。それはとても簡単です。

Convexには、来るたびにすべてのデータをダンプするための多くの選択肢があります。あなたのアプリケーションデータベースは、あなたのアプリケーションのためのものです。

そして、アプリケーションデータベースがある場合、それはおそらくConvexであるべきです。

私がConvexに行くまで、SQLを私のアプリに押し込もうとしていたことをどれだけ理解していなかったかです。それは格段に多くの意味をなしました。

それはORMではありません。薄いレイヤーではありません。アプリの構築をより良くする異なるプリミティブセットです。

多くの点で、それはUncle Bobが推進していたもので、私を含むすべての人が彼にクソを与えたものです。

私のせいでした。私は彼を、SQLがアプリを台無しにしているこの邪悪で恐ろしいものについて、バスルームブランドについてskitso投稿をしていたスパイラルに送りました。

そして、数ヶ月後、私はConvexのために彼に同意します。SQLは私たちのアプリケーションコードに居場所がありません。

SQLはデータ言語です。アプリケーション言語ではありません。理論的に、アプリコードのためのより良いSQLのような新しいものを書くことができるでしょうか?確実に。

Convexは言いました、いや。なぜ気にするのか?代わりにTypescriptを使用してそれを再構築してはどうか?

Convexは、アプリケーションとアプリケーションデータレイヤーを構築するためのTypescriptレイヤーであり、それはとてもよくそれを行います。

とはいえ、これはTSVのためです。TypeScriptを使用していないなら、これはあなたのためではありません。それは大丈夫です。それは絶対に大丈夫です。

あなたのRustとGoの世界で楽しんでください。ユーザーがすることの1%に対して100倍速いものを構築することを楽しんでください。私はあなたたちを誇りに思っています。真剣に、あなたたちは重要で、素晴らしいものを構築しています。

私たちがこの世界で持っているものを汚さないでください。

とはいえ、あなたは彼らのバックエンドをGitHubでチェックするべきです。なぜなら、ConvexはRustで書かれているからです。

Convexは、私たちのためにRustで正しく理想的な同期エンジン、データレイヤー、ORMツールキット、コンパイラ、これらすべての他のものを書いたので、あなたのアプリケーションのためにそれをする必要がありません。

そして、もっと重要なことに、あなたのAIは、あなたのアプリケーションのためにそれをする必要がありません。

ConvexとClaude 4でvibe codingするほど楽しかったことはありません。なぜなら、pretty much any problem を解決するために組み立てることができる良い、シンプル、よく文書化されたプリミティブがあるからです。

そして、ここで私たちはこのセクションに入ります。私が愛するすべての小さなもの。この時点まで、私たちは実際にConvexコードのどれも見ていません。

だから、Convex Chefを使用して作った、バイブコードされたアプリから始めましょう。これは以前に言及したSlackクローンです。

Slackクローンにはチャンネルがあります。認証があります。メッセージがあります。自動同期します。変更すると、更新されます。

クライアントコードから始めましょう。なぜなら、これらのものをどのように消費しているかを見たいからです。更新と物事を処理するために超複雑でなければならないですよね?

const messages equals use query. API messages.list.

私が嫌いな最初の2つのこと。最初のものは、彼らがuse queryという用語を奪うことです。Convex reactパッケージは、use query use mutationをエクスポートします。なぜなら、彼らはオープンソース世界で起こっていることに非常にインスパイアされているからです。

彼らはTRPCとReact Queryとコンボに非常にインスパイアされ、興奮していました。だから、彼らは独自のものを構築しました。

私の本当にホットな意見は、Convexを使用するために、私は彼らのReact Queryバインディングよりも彼らのものを好むということです。ConvexをReact Queryと一緒に使用できますが、これには実際に、Convexのフックを好みます。

ConvexとReactを使用している場合、まだConvexのフックを使用するべきだと思います。しかし、今、コードベースでuse queryを見るたびに、どちらかわからず、それは吸います。利益と否定。だから、それは否定1です。

否定2は、彼らのuse queryフックで、クエリをスキップしたい場合、準備ができるまでこれをしたくない場合、skipを引数として渡すことです。

use queryの第2引数として任意に渡すことができる魔法の文字列引数があり、クエリをスキップします。クール。クソ迷惑です。私は、このような奇妙なクソをする魔法の文字列を嫌います。

設定オブジェクトをくれ。それがReact Queryが移行したものです。それがその開発でそれをする似たようなパターンを持つには早すぎたと思います。迷惑です。

3番目の迷惑なこと。Messagesはデータです。React Queryのように、data, loading, comma, errorを返していません。

messagesがある場合はmessages を返し、ない場合はundefinedを返しています。ああ、そして、エラーが発生した場合は投げます。

だから、それを愛していません。とはいえ、UIにメッセージを取得するために書かなければならないすべてのコードは、これです。

これは、サブスクリプションと同期も処理します。だから、今、メッセージを更新している時、UIで自動的に更新されます。そして、これはただのメッセージです。

私たちが少し下にスクロールして、それを見て、私たちがそれをレンダリングしています。Display messages.m mapap。これは、メッセージについて私たちが変更したことですか?これを見てみましょう。

ああ、私たちが検索している場合、検索結果のみを表示します。そうでなければ、メッセージを表示するだけです。だから、display messagesは、これら2つの配列の一つです。そして、私たちはそれらをレンダリングするだけです。ここで特別なことは何もありません。

メッセージの送信はどうですか?Send message equals use mutation API messages send。

待って、私たちは、ここで成功時に実行する関数を持つon success invalidateのようなものを追加する必要がありませんか?他のクエリを無効にするものを追加しませんか?

これが終了した時に実行する何かを持つ必要がありませんか?他のすべてのツールで行うように?これがどのように単にメッセージを送信して終了できるのか?それは意味をなしません。

私たちが異なるプリミティブを使用していることを理解した時、それは意味をなします。Reactで最初にset stateを呼び出すとUIが変更されることが意味をなさないのと同じ方法で、Convexで最初にmutationを送信するとUIが適切に更新されることが意味をなしません。

だから、ここでメッセージを取得するためのバックエンドコードを見てみましょう。API messages list。

Convex messages list。ここにあります。見つけるのがとても簡単です。Export con list equals query。クエリは、彼らが生成したコードから来ています。

queryは、TRPCと同じようなquery helperです。ここで多くの慣れ親しさを見るでしょう。

Args、これは、私たちが有効な引数を渡していることを確実にするvalidatorであるオブジェクトです。そして、引数が有効である限り呼び出されるhandler、関数。

だから、channel IDはvid channels.。ところで、これは型安全です。Channelsは私たちのスキーマのキーであり、IDを持っています。だから、彼らのvalidator Vを呼び出すことができ、それは迷惑です。なぜなら、ValbotもVだからです。何でも。

小さな迷惑。V do Iidは、ここで持つIDの一つ、ここの値の一つである必要があります。しかし、今、有効なchannel IDでないものを渡すと、handlerにさえ到達しません。

だから、それが実際に文字列であるか、実際に数字であるか、実際にbooleanであるか、何であれ確認できるだけでなく、存在する実際のもののIDであることを確認できます。そして、そうでなければ、コードを実行さえしません。クール。

だから、私たちはget auth user helperでuser IDを取得します。user IDがない場合、エラーを投げます。

それから、インデックスでメッセージdotqueryメッセージを取得します。インデックスは本当にクールです。少し入ります。by channel。だから、ここで、channel IDがargs. channel IDと等しいところを取得しています。

ascending order collect でそれらすべてを取得します。しかし、その時、著者が必要です。なぜなら、メッセージとタイムスタンプやその他何でも見せたいだけでなく、誰がそれを作ったかも見せたいからです。

そして、コードとスキーマを見ると、著者の情報はありません。著者IDがあるだけです。だから、効率的にするために、joinやメッセージをクエリする時に著者をサブクエリする何かをする必要がありませんか?

これは、Reactで最初にset state callがUIで汚く感じる方法と、それがクリックした時に「ああ、クソ、それははるかに良い」と言う方法に非常に似た、最初に本当に汚く感じるもののうちの一つです。

messages.m mapappingして、IDで著者を取得します。そして、さらにクールなのは、認証がデータベースと同じ方法で住んでいないからです。better author next author何でも他のものを使用する時にそうかもしれませんが、ここの著者、ユーザーは、ただのユーザー識別子です。

だから、それは彼らがサインアップしたemailやトークンなどのようなものを持っています。それは彼らの設定、プロフィール画像、これらすべてのものを持っていません。

私たちがそれらを置くのは、profilesスキーマです。私はこれについてハードライン態度を持っています。あなたのアプリケーションテーブルとあなたの認証とOAuthトークン管理テーブルは、異なる問題であり、異なる場所にあるべきです。

あなたの認証の実装詳細があなたのアプリケーションDBに漏れている場合、あなたは今、一つの代わりに4つの問題を持っています。

Profilesはアプリケーションレベルの関心事です。ユーザーが選ぶ表示名、彼らのプロフィール画像のアバター。これらは、アプリケーション特定の詳細です。

ユーザーがどのようにサインインし、彼らのトークンがどのように無効になるかは、アプリケーションの関心事ではありません。それは認証の関心事です。

それを分離し、他の場所に置き、そしてあなたのデータベースのものにリンクすることで、人生がとても簡単になります。なぜなら、ユーザーの有効なトークンでjoinしているのではないからです。ユーザーのIDでjoinしており、彼らのプロフィールでjoinしています。

だから、ここで私たちがすることは、クソコードを書くだけです。message.au IDを呼び出すことでauthorを取得します。authorIDがauthorsに独特であるtype- safe識別子であるため、どのテーブルからかを指定しなければなりません。

それから、プロフィールが欲しい時、より具体的でなければなりません。なぜなら、マッチするもののみを取得し、プロフィールのIDがauthorのIDと異なることを知っているからです。

私たちがスキーマに行く時、それを知っています。user ID vid users。だから、これがリンクされている方法です。

だから、データベースからユーザーを取得します。それから、再びデータベースから彼らのプロフィールと設定を取得します。query profiles with index by user。IDによってユニークなユーザーでユニークなリターンを確実にするために取得します。

avatar URLを取得します。avatar IDがある場合、storageからそのURLを取得します。そして、今、ファイルがあります。なぜなら、ところで、ファイルアップロードも処理するからです。

私たちはまだupload thingを使用していますが、最近のプロジェクトの多くで、Convexに組み込まれているので、気にもしていません。そして、完全に大丈夫に動作します。

そして、今、私たちはこのすべてを返すだけです。そして、これはmapの中にあります。だから、message with authors。

各メッセージに対して、私たちはメッセージを著者にマップします。これらすべてのフォールバックで彼らの名前を置き、ここでavatar URLも置きます。そして、結果を返します。

カスタム構文はありません。奇妙なSQLマッピングはありません。awaitを一度以上呼び出すことを避ける努力はありません。

リクエストとレスポンスの間に複数のブロッキングコールを持たないようにしています。そして、人々はチャットで正しい質問をしています。これはどのようにパフォーマンスが良いのですか?素晴らしい質問。

なぜなら、このコードを見て、何をしているかを知っている時、これはパフォーマンスが良くありえないからです。

これがどのように実装されているかについて知る重要な詳細があります。あなたが私の言葉を信じて、これがパフォーマンスが良く、先に進みたいなら、それは私には良いです。

しかし、私はこれらの詳細が好きです。それらはクールです。このコードは、このAPIは、Nodeで実行されません。これは伝統的なnodeサーバーで実行されないNode.js関数ではありません。

それは、workerdに少し似ていますが、Cloudflare workersが実行されているものですが、また非常に異なります。それは、彼らがRustで構築した最小限のカスタムランタイムです。

V8にまだ基づいていると思いますが、重要ないくつかのことを引き継ぐ彼らのランタイムです。

例えば、多くのものを挿入している場合、ここではメッセージを送信しています。created atが欲しく、ここでnew dateを行った場合。

一度に4つのメッセージを送信したく、すべて同じ日付を持ちたい場合、正しいことをすることができます。それは、const sent at equals new dateで、それを再利用することです。

しかし、ばかで代わりにこの方法でそれを行う場合、Convexを使用しない限り、それらすべてに異なる日付を取得するでしょう。それから、彼らは、リクエスト時にこれが返すものはこのリクエスト全体にとって一貫していることを確実にするでしょう。

これは、彼らが行った、最初に聞いた時、私の邪魔をし、私を苛立たせると思ったことの多くの例の一つです。彼らは文字通り一度も私を混乱させたことがありません。

それは機能するだけです。なぜなら、彼らのカスタムランタイムには、DBでこれらのawaitコールを行っている時、それをブロックして各待ちをしないという一つの大きなキー機能があるからです。

それは、ここで行ったすべてを取り、それを平坦化し、単一のトランザクションにして、あなたのために発火するつもりです。クエリと、はるかに重要なことに、mutationの両方のために。

なぜなら、ここで行うすべては、元に戻され、再生され、CRDTのクソに完璧に従うことができるからです。だから、20の異なることをしなければならないmutationを行っている場合、19まで大丈夫で通り、20番目が失敗すると、それを部分的にコミットされた状態に残しません。

それはすべてをロールバックします。何も起こりません。

それは、ここで書くTranscriptをTypeScriptコンパイルステップとして使用して、実際に発火する必要があるトランザクションを生成するようなものです。実際、Nickからのこの類推を愛しています。React serverバットワークのようなものです。

詳細的には、絶対にそうではありません。しかし、概念的には、100%そうです。だから、あなたは愚かでシンプルで、明白で、簡単で、間違ったTypeScriptコードを書くことができ、出てくるものはクソ速いです。

あなたは、それが私たちがforループとmapでバニラTypeScriptを書き、それが想定通りに動作することがどれほど素晴らしいかを知っていますか?SQLは型安全ではないので、AIがSQLを書くことは得意ですが、間違って書いたら、実行するまでわからないので、AIにとってさらに素晴らしいです。

そして今、重要な質問を得ています。なぜなら、私が持っていたのと同じだからです。コンパイラが厄介である場合を決して経験したことがありません。わかりません。

それがどうやってか、クソ黒魔術です。それはただ想定されることを行います。クレイジーです。

コンパイラのためではなく、キャッシュレイヤーのために厄介であるエッジがあります。そして、それでも、それは彼らが修正している小さなクソです。

そう、Dom、あなたは正しいです。これはUncle Bobの問題への解決策です。

それは信じられません。それは私が構築する方法をとても簡単でより信頼できるものにし、そしてcursorやclaude codeや他のクソでバイブコードアウトするのをずっと良くしました。

そして、私たちはすべてがTypeScriptであるため、最もクールな部分にさえまだ到達していません。すべてが型安全です。すべてがすべてが何であるかを知っています。

このコードをダウンロードすると、ここにそのコードベースがenv.localとしてあります。ここには本当にシークレットであるものは何もないことに注意してください。それは重要ではありません。デプロイキー。クール。私の開発ものにデプロイできます。何でも。それが重要でないので、私はこれを殺すつもりです。

npmとクソを使用しています。それも削除するつもりです。

PNPM install。dev front endとdev back end。しかし、私はdev back endを実行するつもりです。だから、実際にこのrundev backendは実行したくありません。今、それは生成をスピンアップするつもりです。ところで、あなたは生成されたファイルをコミットします。だから、そのすべてを行う必要さえありません。私は選んでいるだけです。

ああ、どこかにデプロイする必要があります。通常、私はバックエンドでこれすべてを設定し、すべてを自分でセットアップしなければならないでしょう。いや。

新しいプロジェクト、OBRのチームを作成します。なぜなら、私は既にサインインしているからです。CloudまたはLocal。バックエンドをローカルで実行したい場合、できます。私はしません。クラウドを使用するつもりです。

今、私はこれすべてをConvexでプロビジョンしました。ただクリックするだけで、そこにいます。すべて終了。

すべてのテーブルがセットアップされました。すべての認証が処理されました。すべてが終了しました。私たちは良いです。

だから、今、私が見せたかったのは型安全性です。UIに戻りましょう。メッセージエリアに入りましょう。

Messagesはuse queryです。ああ、どんな型エラーを得ていますか?Promise returning。

ああ、あなたがものを明示的にvoidしなければならないリントルールがあります。何でも。気にしません。それを残します。大したことではありません。

しかし、ここにmessagesがあり、これをホバーすると、正確な型のauthor name string avatar URL string or null IDアンダースコアが組み込みIDのため、作成時間、その他すべてが私たちのデータベースにあるフィールドです。そして、これをcommandクリックすると、そのデータを取得するバックエンド関数に連れて行かれます。

TRPCマジックの巨大な部分は、これをnameからtitleに変更した時に何が起こるかを見てください。保存していませんし、2つのエラーから5つに行きました。Command Z、2つに戻ります。Command shift Z、5つに戻ります。

生成されたコードが、あなたが書くTypeScriptファイルの型定義へのポインターを生成しているだけだからです。

サーバーを完全に殺すことができます。

だから、このアプリのために何も実行していませんし、保存の発生なしでさえ、型安全性のすべてを得ています。

コードジェンであっても、コードジェンがポインターを生成しているので、型定義を生成していません。そのため、すべてがインターフェースし、扱うのが大幅に簡単になります。

そして今、UIと互換性のない方法でスキーマを変更すると、UIで型エラーが発生します。ここでデータを返す方法を変更すると、このファイルでエラーが発生しません。それが消費される場所でエラーが発生します。

エラーは、エラーが現れる場所に行きます。これは、私たちがコードを書く時に素晴らしいです。なぜなら、変更を加えた時に何が壊れるかを見ることができるからです。

しかし、AIにとってさらに良いです。なぜなら、データベースを変更してUIが期待と一致しないというエラーを得ていないからです。UIでエラーを得ます。

だから、AIは間違った型を返したと言うエラーを得て、それを変更し、それから別のエラーを下流で得て、それを変更し、それから5回の変更の後にようやくコンポーネントに到達し、ああ間違ったことをしたと理解しません。

データベースを変更してUIが期待と一致しなければ、UIでエラーを得ます。とても良いです。

これが私がTRPCにオールインした理由です。なぜなら、フルバックからフロントエンドへのこの型安全性のパイプが、構築をとても簡単でより信頼できるものにするからです。そして、それはConvexがどのように動作するかの一部にすぎません。

そして、気づいたらこれらの小さなことがたくさんあり、あなたが彼らの異なるプリミティブセットを買うと、人生をとても良くします。

だから、これはどのようにライブ更新しますか?それについてさえ話していません。

まあ、messagesを見てみましょう。send を具体的に見てみましょう。

channel IDを取り、どのチャンネルに行くかを知り、contentを取り、何を投稿したいかを知ります。User ID、await、get auth。まったく同じこと。それが起こることを望まない時にただ投げます。

ユーザーがこのチャンネルの一部かどうかをここでチェックできます。私たちが好きなら。だから、const channel get that if no channel、私たちはそれから、ユーザーがまったく同じ方法でチャンネルにいるかどうかをここでチェックできます。

そして、実際にメッセージを挿入するために、context.db.insert テーブルの名前、そして挿入したいもののオブジェクト。

複数のものを挿入する方法を推測してください。そうです、forループです。それはただのTypeScriptです。

だから、更新はどこで起こりますか?UIはどのように変更されますか?私が以前に言ったことを覚えていますか、それは実質的にここでのあなたのコードをトランザクションにコンパイルしていると。

ルックアップのためだけにそのトランザクションをコンパイルしているのではありません。それをキャッシュキーとしてコンパイルしています。

それは、ヒットされるすべての行と、このリクエストを解決するために重要なすべてのピースを取り、それらにキャッシュキーを与え、そして、新しいメッセージを追加するような、そのキャッシュキーに影響するであろう何かをする時、それはそのキャッシュキーを無効にし、更新を送信します。

ここで書くクエリをコンパイルされたトランザクションとして扱う魔法は、トランザクションを高速化するだけでなく、何がそれを変更した可能性があるかについて、本当に強いレベルの内省を与えてくれます。

再び、それは非常にreactyです。自動的に更新するからというだけでなく、これらの部品とそれらが構築したわずかに高い抽象化との関係が、いつ物事が変更され、それに応じて更新するかを識別することをとても簡単にするからです。

これが、私がデータベースで直接変更する時に、コードを実行せずに、ただ動作する理由でもあります。

わかりました、私はConvexが私の脳を完全に再配線した方法の高いレベルをカバーしたと思いますが、私が愛するこれらすべての小さなことには入っていません。

今後の展開と議論

webhookがどれだけ簡単か、開発体験がどれだけ良いかから、seed関数を実行するような物事を行う方法、マイグレーションについてどのように考えるか、work pools、彼らのコンポーネントモデルまで。

私が本当に愛している彼らについてのこれらすべての小さなことがあり、それは独自のビデオのように感じます。

私は完全にここに座って、これすべてを一つのビデオとして行う準備ができていましたが、なぜ私がConvexを好きかをここでよく伝えたと感じます。

将来、私が愛するすべての小さなことについて別のビデオをするべきだと思うなら、コメントで教えてください。そして、それを確実にします。

最後に一つ、Convexに対する議論に飛び込む必要があります。そして、覚えておいてください、私はオールインして、すべてを賭ける前に、約4年間、かなりアンチConvexでした。

だから、これらのいくつかを見ていきましょう。そして、私はTwitchチャットとも話しているので、皆さんも独自の懐疑的な意見を尋ねることができます。Convexが意味をなさないと思う理由を教えてください。

「これはフロントエンドからデータベースに直接接続するように感じます。」

私はこれのために図さえ持っています。GraphQLについてですが、同じ違いです。GraphQLはここに行きます、ここではありません。データベースとサーバーの間、サーバーとユーザーの間ではありません。

この図全体がConvexによって台無しになります。しかし、まだこの方法で考えているなら、それは理にかなっています。

Firebaseで構築している時のように、スキーマを定義しています。スキーマで権限を定義し、それからクライアントサイドのユーザーは実質的に直接データベースを叩きます。

これが、Convexが異なって行う最大のもののうちの一つです。ここに私たちのスキーマがあります。データベースにあるすべてのもの。ユーザーはこれらのどれにもアクセスできません。

これらはクライアントから叩くことができません。データベースで物事を読み書きできる唯一の方法は、クエリとmutationを定義することです。

あなたがクライアントサイドで何らかのクソに書くことはできません。私の懸念では、これは完全にEva証明です。

皆さんがEvaに慣れていないなら、彼女は数百の会社をパウンしたハッカーです。なぜなら、彼らがFirebaseを使用し、彼女が書くことができる特定のテーブルを認証し忘れ、それからArcを使用していたのであなたのコンピューターをハックしたからです。

EvaはFirebaseコードベースにひどいことをしました。なぜなら、Firebaseがデータアクセスの悪いパターンを奨励するからです。Convexはあなたをそれらのパターンからブロックします。それはできません。

データベースからデータを取得する方法は、実質的にエンドポイントである関数を書くことです。それがデータベースからデータを取得する方法です。

ユーザーはスキーマを叩くことができません。任意のものをクエリできません。ユーザーはクエリとmutationを通してあなたが彼らのために定義するポータルを通してのみ、あなたのデータに到達できます。

そのアクセスレイヤーを定義しなければならない時に消える問題の量は膨大です。問題は、そのアクセスレイヤーを定義することが以前はあまりにも高価だったことです。

そして、フロントエンド開発者とアプリ開発者は特に、それをここで行う方法を理解するのをあまりにも嫌いました。そうではありません。

あなたは実質的にTypeScriptを書くだけです。関数を書くようなものです。

これをFirebaseで書いたであろうもの、しかし今はConvexでサーバーで書いているのと、ほとんど考えることができます。

そして、それはトランザクションの平坦化、キャッシュキー、これらすべての他のもののような、すべてのクールなパフォーマンス特性を与えてくれます。しかし、それは まだユーザーが定義しているサーバー上のエンドポイントです。

ユーザーはこのコードを実行できません。ユーザーは、さらに重要なことに、このコードをスキップできません。彼らはこの関数を叩くことができます。

だから、Firebaseのように動作すると感じたためにConvexを避けていたなら、あなたの留保を理解します。Firebaseについて正しいです。Convexについて間違っています。

クエリとmutationを定義しなければなりません。それらはスタートアップです、ただそれはおそらくスケールしません。

これは私が本当に感じた他のもののうちの一つです。多くのユーザーを得るものを構築するので、Convexを使用できないと確信していました。

T3 Chatは多くのデータベースを崩壊させました。率直に言って、Supabaseは T3 chatの重みの下ですぐに崩壊するでしょう。

テスト負荷で簡潔に試しましたが、即座に崩壊しました。私たちが行うことは、スケールしないデータベースでは動作しません。それが私たちがplanet scaleをそれほど愛した理由です。

そして、Convexに移行した時、planet scaleが恋しかったです。だから、私は彼らをキスさせるためにいじめました。そして今、convexはplanet scaleの上に構築されています。

しかし、convexがplanet scaleの上に構築されているのは、人々が持つ留保の一部を処理するのに役立つクールで楽しい実装詳細のようなものです。しかし、私をはるかに興奮させたのは、彼らがSam sniff testに合格したことでした。

Sam LambertはPlanet ScaleのCEOです。彼は、データベースのすべてについて、来るほど選り好みです。

すべてのデータベース製品がどれほど哀れで、Postgressについて私たちが嫌いなすべてのことについて、彼と私が何回話したかを言うことはできません。

彼は私が知っている最も賢いデータベース人の一人です、彼の従業員の2、3人以外は。

私が彼をConvexの人たちに紹介した時、彼は数日後のイベントで私のところに非常に興奮してやって来て、「彼らを雇いたい」と言いました。

Samが私に導入した誰についてもそれを言ったのを聞いたことがありません。彼らは彼のデータベース嗅覚テスト、データ管理とすべてのテストに合格しました。なぜなら、彼らは何をしているかを知っているからです。

Convex創設者は、Dropboxをスケールした人たちです。彼らはS3でパフォーマンス問題を発見した人たちです。彼らは本当に何をしているかを知っています。

そして、Samはすぐに彼らでそれに気づきました。これは私にとって巨大な「ああクソ、彼らはこれをできる」瞬間でした。これは大きな、それがクリックしたようなものでした。

そして今、この特定のビデオで持つことが重要だと思う、最も重要なプッシュバックのピースのために。

ロックインについてはどうですか?私は過去にロックインについて多く話しており、私の現在の方法論と考え方がクリックする方法に時間がかかりました。私が説明できると思う方法で。

しかし、2種類のロックインがあります。人々が懸念しているタイプだと思うものがあります。それは、プラットフォームまたはプロバイダー特定のコードです。

この例については、私が働いているGelのようなものを見ることができます。私がアドバイザーである本当にクールなデータベース会社でもあります。

彼らは、はるかに良いグラフィングと関係データを作るために、クエリ言語とデータベースの実行方法を再考しています。彼らのデータモデルは本当にクールです。彼らが素晴らしいことをしていると思います。

彼らは独自の構文、gelを持っています。彼らは以前edge DBでした、ところで、これをかすかに思い出しているなら。彼らの古い名前はedgeでした。

今、彼らはgelです。構文、言語、データベース、これらすべての部品は彼ら独自のものです。だから、gelに基づいてコードを書くと、多くのことがあなたにとってずっと簡単になります。

奇妙な関係と、それらを通しての数学とクソを行うための構文は、従来のSQLよりも大幅に良いです。

しかし、移行することを決めた時も、これはまだHQLです、gelではありません。彼らはまだすべてを更新していません。それは面白いです。

要点は、このクエリを書くと、今、この他の言語、この他の構文、この他の構築方法のすべてがあります。ただ移行することはできません。

あなたはこのプロバイダーに特定の多くのコード、多くのものを書いています。それを自分でホストできるとしても、他のことでそれでできるとしても、あなたはまだ彼らの考え方にロックされています。

だから、他のタイプは何ですか?プラットフォームプロバイダー特定のコードがあります。他のタイプは、プラットフォームが他の方法で自分で書いたであろうものを提供することです。

これは、VercelでのロックインへのSQLainについて私が多く考えることです。人々は、Next.jsミドルウェアに怒っていました。なぜなら、ミドルウェアはエッジで実行され、残りは従来のサーバーで、従来のnodeインスタンスで実行されるからです。

それは、望むなら自分で実装できるインフラ詳細です。しかし、Next.jsはフレームワークなので、あなたのためにそれを魔法的にできません。インフラではありません。

だから、その機能が欲しく、Next.jsを使用しているなら、その機能を持つ最も簡単な方法は、Vercelでそれを行うことです。他のプラットフォームはこの機能を追加できます。

自分で構築することもできますが、それをしないためにVerselを使用しています。彼らはあなたがこのコードを書くことを防いでいます。

incremental static revalidationがどのように動作するかについても同じです。Nex in Vercelでのキャッシングのほとんどがどのように動作するかについても同じです。画像最適化についても同じです。サーバーコンポーネントについても同じです。

これらすべての多くのものについて同じです。VercelからCloudflareに移行する時、あなたは異なるコードでコードを置き換えているのではなく、Vercelがあなたにスキップさせてくれたコードを書いているのです。

だから、Verselにいるなら、彼らはこれらすべての素晴らしいもをあなたのために提供し、あなたが決める、わかった、私はCloudflareに移行している、またはNetlifyに移行している、またはAWSに移行して、Lambdaで自分でホストしている、そのタイプの動きをするためにGitHubに提出しているpull requestのdiffは、プラス8,000マイナス0です。

そのタイプの動きをする時、コードを削除していません。多くの場合、私はそれをロックインとさえ知覚しません。それは、他の方法で自分で書いたであろうもをあなたに提供するプラットフォームです。

だから、Vercelでの多くのロックインを知覚しません。Vercelは、私のコードを実行し、一つの場所からデータを取って、ユーザーに与えることを可能にするパイプのセットです。

Convexで奇妙なのは、それが両方の少しだということです。Convexには、これらの両方のバケツに適合する部品があります。

そして、これを自信を持って言うことができます。なぜなら、Convexが行うすべてのことを以前に自分で書かなければならず、それがクソ吸ったからです。

Vercelから移行することがロックインのように感じるのは、突然多くのコードを書いているからですが、以前に書いたコードを削除して置き換えているのではありません。

あなたはVercel特定のコードを書いていません。Vercelがその全時間書くことを保ってくれたコードの代価を払っているのです。

Convexは主にそれです。私のデータベースと私のユーザーの間で完全な型安全性を持ちたいなら、3つのツールを持ち込み、自分でそのための多くのものを構築できます。

何かが変更されてすべての人が更新を得る同期が動作することを望むなら、pusherを引っ張ることができます。独自のウォッチャーレイヤーを追加し、websocketsを通して自分ですべてを送ることができます。

Convexで私が気にするすべてのことは、自分で構築できたであろうことです。そして、私がより悪いConvexをDIYしていることを理解した時、それが移行した時です。

しかし、望むなら自己ホストもできます。今では、特に自己ホストするのは非常に驚くほど簡単です。だから、移行して自分でホストしたいなら、素晴らしい。それができます。

移行して再び独自のコードを書きたいなら、クール。それができます。削除しなければならないものがあります。

convexディレクトリのほとんどすべては、Convexに特定です。だから、その意味では、いくらかロックされています。

しかし、クライアントサイドのコードの多くはまだそこにあるでしょう。そして、正直に言って、ここで書いているコードは比較的シンプルで最小限です。

Convexから移行した時、これをSQLで代わりに書き直さなければならないでしょう。

しかし、ロックインについて考える時により考えているのは、自己ホストできるか?この会社にお金を払うのをやめることができるか?移行するために捨てなければならない作業はどれくらいか?

Next.jsで、自己ホストできるか?はい。会社を止めることができるか?絶対に。移行するために捨てなければならない作業はどれくらいか?なし。

しかし、移行するためにしなければならない作業はどれくらいか?これらは、頭の中でロックイン方程式を行う時に考える異なるピースです。

だから、Vercelで、はい。会社を止める、はい。捨てなければならない作業、なし。移行するためにしなければならない作業はどれくらいか?トン。

しかし、その作業は、NextやVercelと関係のあることではありません。それは、彼らから始めていなかったら、とにかくしなければならなかった作業です。

だから、Vercelを使用することをロックインとして見ません。Vercelを使用することを、あなたのアプリケーションにキーでないこの種のクソ作業の束をしないことを選択することとして見ます。

CDNとキャッシュレイヤーをセットアップする数百時間が、月10ドルより価値が低いなら、なぜこのビデオを見ているのかわかりません。

しかし、生計を立てている私たちの残りの開発者にとって、それは価値のあるトレードです。

あなたのデータが関わっている時、それははるかに怖いです。だから、ここでの留保を理解します。

スタートアップがあなたが支払っているクラウドでデータをホストしており、彼らのSDKと、TypeScriptをあなたがアクセスできないデータベースで実行されるトランザクションに変える彼らの奇妙なコンパイルレイヤーを通してのみアクセスできるなら。

それははるかにロックインのように感じます。しかし、何らかの理由で、Convexは移行することを本当に簡単にすることに決めました。

データベースを他の場所に同期することは些細なことです。バインドして他の場所にリンクを追加し、データをコピーするだけです。

代わりに望む方法で行うためにクエリコードを書き直すことができます。独自のuse queryフックのカスタムバージョンを書き、そのすべてを自分で再定義することができます。

または、あなたが探しているもの、自己ホストすることによって請求書を下げることを得ることができます。なぜなら、それはすべて自己ホスト可能で、データを移行して幸せになるだけです。

Convexから移行する時、このフォルダを削除しなければなりませんか?Convexから完全に移行するなら、はい。しかし、彼らのクラウドから移行するなら、いいえ。自分でホストするだけです。

しかし、私が書いているすべてのコードは、それらを決して使用していなかったら書いたであろう同じコードです。そして、私はそれを選択しました。

私は反対の方向に行くことを選択しました。Convexが私たちのために提供してくれるコードを書き、それを嫌い、Convexに物事を動かしてもらうことを支持して、それをすべて捨てることを選択しました。

そして、結果として、私たちの請求書はずっと安くなりました。現在、Vercel請求書で月約800ドル節約しています。そして、先ほど行った変更で、すぐにさらに500ドル節約します。

Planet Scale請求書で800ドル節約しています。そして、合計で600ドル月額かかると思います。だから、1,500ドル以上節約し、600ドルかかります。

だから、あなたの懸念が私たちの規模でのコストなら、あなたは大丈夫です。それは素晴らしく処理します。

うまくいけば、それがロックインの懸念に対処するのに役立ちます。

楽しい質問です。「インフラがすべてオープンなら、Convexは他の独占的製品と比較して多くの企業契約を持たないことを考慮して、どのように十分なお金を稼ぐのですか?」

素晴らしい質問。彼らは少し異なる賭けをしています。

彼らは、そして私も今信じていますが、スタートアップが来て、問題の解決策としてConvexを選び、より伝統的な企業ソリューションを使用している会社と競争している場合、Convexを使用している会社は、はるかに速く出荷し、製品市場適合をもっと早く叩き、はるかに安く到達し、結果としてはるかに成功するでしょう。

私はこれを知っています。なぜなら、Convexを使用していない私たちの競合他社は、私たちよりもはるかに遅く動いており、私たちよりも悪い体験を持っているからです。

そのため、私たちはより成功することができます。そして、Convexの顧客の多くは、6ヶ月以上で彼らにお金をほとんど作りません。

しかし、6ヶ月で、顧客の100分の1が今月数千ドルを費やしているなら、あなたは大丈夫です。

そして、世界で最高のインフラエンジニアチームの一つが、比較的安い料金で私たちのためにそれすべてを行うことができる時、これらのものを自分でホストしようとすることがなぜ世界で意味をなすのでしょうか?

それは世界で意味をなしません。クソAnthropic一人での私たちのモデルプロバイダーの一人に対する私たちの請求書は、最低月3万ドルです。そして、すべてのための私たちのデータベース、すべてのための私たちの同期エンジン。

私たちのアプリケーションのすべてがどのように動作するかのための私たちのレイヤーは、3万対600ドル月額です。3万に対して何を疑うのですか?

「それがどれほど良く見えるかに懐疑的で、何かが良すぎて真実でない時はいつでも、それは私の尻を噛みます。」同意します。

しかし、これでクールなのは、Convexでクリックしたものです。あなたのアプリを乗っ取る一つの大きなもののようなものではありません。

それは、これらすべての小さなプリミティブで、これらすべてのプリミティブは、超タイトでよく設計されており、それからも本当によく構成されます。

ReactはPromiseとして狂気で不可能に聞こえますが、hooksは意味をなし、componentsは意味をなし、life cycleは意味をなし、packagesは意味をなし、それからそれらすべてが一緒になって、本当によく動作するこのものになります。

Convex componentsのようなものは、私が既に言及した、おそらく行うであろうフォローアップビデオで、Convexについて愛するすべての小さなもので、彼らは本当に本当にクールだからです。

しかし、私はConvexに非常に幸せで、皆さんが私がそれと恋に落ちた方法のビットを見ることを願います。

そして、私に似ていて、それを見て、「ええ、それは大丈夫に見えるが、私が構築している物のためではない。私は実際のアプリケーションを出荷している。より多くのコントロールが必要。私のアプリをスケールしている。これは小さなサイドプロジェクトのため」と言ったなら。

私はほぼ4年間、それについて間違っていました。そして、私が犯したのと同じ間違いをすることからあなたを防ぐことができることを願います。

これらの人たちは合法です。

あなたの構築方法を完全に変えるかもしれないものを見逃さないでください。なぜなら、それは私にとってそうだったからです。

この遠すぎる長い咆哮を聞いてくれてありがとうございます。私がConvexから得る価値を適切に伝えたことを願います。

皆さんがどう思うか教えてください。そして、次回まで、peace nerds.

コメント

タイトルとURLをコピーしました