前説:2026年2月あたりからAIがあればSaaSが不要と話題になっている
まあ、上の記事のように「バズワード=オーバーアクション的な部分」もあるが、昨今のAI(claudeCode)のソースコード生成ってのは、非常に「優秀」で「筆者のようなロートルエンジニア」だと
手前「クールな顔で強気な風体を有しているフリ」をするけど、だけど「実際にはAIに勝てねえ!!」って思うわけで、正に
- パラダイムシフト(物の見方や価値観が、革命的・劇的に変化)
だなあって感じる次第です。
ただ、最近 ClaudeCode 初めました的な「正に夏に冷やし中華がメニューに掲載される」的なレベルの「にわかClaudeCode初めました」なので、まだまだ「クンフーが足らない」中での「記事」なので、いや「お前ニワカすぎやろ」って思われてもご勘弁を。
この記事を読むと理解出来ること
- AI(ClaudeCode)を使って、ソースコードが書けるんだって共感できる
- ただAI熟練者にとって、超当たり前である事を書いている
- 筆者作成の自作フレームワーク minto(llrtと言うaws lambda 特化の nodejs 代替えプロジェクトを使った超軽量フレームワーク)と言う「かなりコスパを意識した小規模フレームワーク」と自画自賛しているが、一方で「超ニッチな自作フレームワーク=全然有名じゃないもの」を使って「非エンジニアでもclaudeCodeを使ってWebアプリが作れる」的な話をしたい
はじめに
筆者は以下自作フレームワーク minto と言う AWSの関数URLでの serverss-FW を作っており
また、minto では以下の AWS LLRT と言う
Nodejs の代替え的な AWS Lambda に特化した「Lambda上でNodejsの10倍近く高速+低メモリ」で動作する環境が存在し、それに対応しているフレームワーク=minto となっています。
ただ、これを作ったが「当然個人が作ってるだけ」なので、本人以外は誰も使わない=ニッチ過ぎるわけだけど、これを使って「実際にWebアプリを実装しよう」とする場合、果たして「有名フレームワークでWebアプリをAIで作成する」のと違って、AIでは超ニッチな環境だと「Webアプリが作れない」のかってのを検証する意味でもこの記事が役立つのかなって思います。
ってわけなんですが、その前に筆者的に「冒頭のSaaSが消える記事」を見ていて「これAIで minto もワンちゃん非エンジニアでもコーディングできるんじゃねえ?」って思ったので、この記事を記載した次第です。
早速始めよう 自作フレームワークmintoで小規模社内Webアプリ作成
ここで作成されたサンプルは以下
にあるので、それらを見ながらでお願いいたします。
はじめに解説からですが、何年か前にリリースされた、aws lambdaでの「関数URL」ってのは、これまでのAWS API-Gateway+Lambda と違って「簡単+lambda単体」でWebアプリが作成でき、一方で関数URLでのURLはランダムでユニークなURLが作成されます。
なので「セキュリティー的にはかなり微妙な部分」もありますが、これプラス
- ユーザーパスワードログイン機構
これがあれば、とりあえず「URLさえわからなければ、もしくは定期的にURLの更新の運用を行えば、通常公開のWebアプリのように2段階認証」をするほどじゃないと言う「今どきのセキュアーじゃない仕組み」で、とりあえず「ClaudeCode」でログイン実装Webアプリを作成したいと思います。
まず「ClaudeCodeのページにジャンプ」して、以下のメッセージを打ち込みます。
https://raw.githubusercontent.com/maachang/minto/refs/heads/main/lambda/src/index.js このindex.js のソースコードは、AWS Lambda の javascript ソースコードの実行mainプログラムで、これは「関数URL」で動作するものである。この機能を使って、ログイン・ログアウトができるWebアプリを作成してほしい。
筆者にわかClaudeCode初めましたなので、普通にGithubRepogitoryのURLだと、これパブリックなRepogitoryなのに、うまく読み込めないと連呼され「README.mdを参照します」って事になり、想定したソースコードを作成してくれなかったので、このようにRAWなソースコードを対象としています。
すると「一旦プログラムを出力してくれる」けど、そうすると「ログインユーザがJSON設定、セッション周りの情報がオンメモリー」で使い物にならないプログラムとなっていました。
なので、次に以下のメッセージでS3に出力する形としました。
ログイン・ログアウトのセッション情報は、AWS S3 に保存する形で、そして「ログインユーザ情報+パスワード」も「S3で保存する形」のもので作って欲しい
これを行う事で先程の懸念点だった「ログインユーザの情報管理」や「オンメモリでのセッション管理」が「S3に保存される=永続化」される形となりました。
だけど「動的なHTML部分が、minto 機能の jhtml テンプレートエンジンを利用できてない」内容だったので、今度は以下のメッセージで「jhtml テンプレートエンジンを利用してほしい」旨を説明しました。
また、jhtml( mt.html) のファイルは、以下URLのHTMLテンプレートエンジンを利用して実装してほしい。URL: https://raw.githubusercontent.com/maachang/minto/refs/heads/main/tools/jhtml.js
その結果が「冒頭の minto GithubRepogitory のサンプル結果」
となります。
claudeCodeで作成されたプログラム内容
// ============================================================
// minto ログイン・ログアウト Webアプリ
// AWS Lambda 関数URL + S3 + jhtml テンプレートエンジン
// ============================================================
//
// ■ ディレクトリ構成
//
// lambda/
// ├── src/
// │ └── index.js (minto本体 ※既存)
// ├── tools/
// │ └── jhtml.js (jhtmlテンプレートエンジン ※既存)
// ├── public/
// │ ├── filter.mt.js (認証フィルター)
// │ ├── index.mt.html (ログインページ)
// │ ├── login.mt.js (ログインAPI)
// │ ├── logout.mt.js (ログアウトAPI)
// │ ├── mypage.mt.html (マイページ)
// │ ├── register.mt.html (ユーザー登録ページ)
// │ ├── api/
// │ │ └── register.mt.js (ユーザー登録API)
// │ └── assets/
// │ └── style.css (スタイルシート)
// ├── lib/
// │ ├── s3client.js (S3操作 共通モジュール)
// │ ├── session.js (S3セッション管理)
// │ └── userStore.js (S3ユーザー管理)
// └── conf/
// └── app.json (アプリ設定)
//
//
// ■ S3 バケット構成
//
// s3://<BUCKET>/
// ├── sessions/<sessionId>.json
// └── users/<userId>.json
//
//
// ■ jhtml テンプレートエンジンの組み込み方法
//
// Lambdaエントリポイント(起動スクリプト)で以下を実行:
//
// const mintoIndex = require("./src/index.js");
// const jhtml = require("./tools/jhtml.js");
// mintoIndex.setJHTMLConvFunc(jhtml.convert);
//
// これにより .mt.html ファイルが実行時に自動的に
// jhtml.convert() で .jhtml.js 相当に変換され実行される.
//
// ※ 事前変換する場合:
// jhtml.convert(fs.readFileSync("xxx.mt.html").toString())
// の結果を xxx.jhtml.js として保存してデプロイすれば
// setJHTMLConvFunc は不要.
//
//
// ■ jhtml テンプレート構文 (tools/jhtml.js 準拠)
//
// <% ... %> JS実行(出力なし)
// <%= expr %> 式の結果をHTML出力
// <%# ... %> コメント(何も出力しない)
// ${ expr } テンプレート出力 (<%= expr %> と同等)
// $out("string") プログラム的にHTML出力
//
// 変換後は以下の形になる:
// exports.handler = async function() {
// let _$outString = "";
// const $out = function(n) { _$outString += n; };
// ... (変換されたコード) ...
// return _$outString;
// }
//
// ※ handler内では minto グローバル変数が利用可能:
// $request(), $response(), $loadLib(), $loadConf(),
// $require(), $mime(), $requestId(), $getNow(),
// HttpError, rand, createRandom
//
//
// ■ Lambda 実行ロールに必要な IAM ポリシー
//
// {
// "Effect": "Allow",
// "Action": [
// "s3:GetObject", "s3:PutObject",
// "s3:DeleteObject", "s3:ListBucket"
// ],
// "Resource": [
// "arn:aws:s3:::<BUCKET>",
// "arn:aws:s3:::<BUCKET>/*"
// ]
// }
//
// ============================================================
いやあ「すごいなあってのが」これ「claudeCodeが index.jsやjhtml.js などのソースコードから、その中身を理解して、その仕様に合わせて実装」してくれて、それを元にログイン・ログアウトと言うありきたりだけど、必要な実装を行ってくれるわけです。
あと「claudeCode が作成してくれたソースコードの内容」は以下
で、markdownで保存しています。
次に実際にclaudeCode作成のログイン・ログアウトを実行してみる
まずAWS Lambda の構築からなのですが、この辺は過去の記事の通り作成します。
- AWS Lambda のレイヤーに llrt-lambda-arm64-full-sdk.zip を登録する
- AWS Lambda を「Amazon Linux 2023」でCPUを ARM で作成する
- AWS Lambda の「ランタイムのハンドラ=index.handler」に変更する
- AWS Lambda の「関数URL」を有効にする
- 以下のIAMポリシーを作成し、対象AWS Lambda のIAM Role に割り当てる
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:List*",
"s3:Get*"
],
"Resource": [
"arn:aws:s3:::test-minto-llo-bucket",
"arn:aws:s3:::test-minto-llo-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::test-minto-llo-bucket/*"
]
}
]
}
(test-minto-llo-bucketの名前は環境に合わせて対応してください)
これでAWS Lambda 側の準備が完了なので、次に「mintoをGithubRepogitoryからダウンロード」して、loginLogoutサンプルを mtpk -all で「デプロイ対応」して、AWS Lambda に「アップロード」します。
これで動作するための環境が作れたので、これでログイン画面を開いてみます。
ログイン画面が表示されます。
ただ、ユーザ情報は存在しないので「下の新規作成」で、ユーザ作成します。
ユーザ情報を登録します。
ログイン後マイページ画面が表示されました。
- その他
- ログインしていないのに、マイページが閲覧できてしまうか検証:ログイン画面に遷移しました
- ログイン中にログイン画面のURL:マイページに遷移しました
一旦上にあるように「ログイン時にログイン画面行った時の振る舞い」や「ログアウト後にログイン中しか見れないページが見られてしまうのか」の確認は問題なさそうでした。
次にClaudeCodeが作成してくれたコードは問題なく動きましたが、一方で
- 修正が必要だった箇所
修正が必要だった箇所は以下の箇所となります。
- lib/s3client.js
// [async]StreamをStringに変換.
//const _streamToString = async function (stream) {
const _streamToString = function (stream) {
// TypeError: not a function at _streamToString エラーになる
// ので、恐らく llrt が この構文非対応の可能性がある.
// ここの for await 部分を書き換える.
/*const chunks = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
return Buffer.concat(chunks).toString("utf-8");*/
return stream.transformToString("urf-8");
};
この部分だけど、前のコード(for await (const chunk of stream))でも Node.js なら普通に動きますが、今回利用するのが llrt(https://github.com/awslabs/llrt) であり、まだ beta版でのあるので、この for await (const chunk of stream) がうまく認識できないみたいでした。
TypeError: not a function at _streamToString (__cjs:/var/task/lib/s3client.js:19:29)
ちょうどこの処理は
- S3Getでの取得結果=Stream型 これを文字列に変換する処理
だったので、単純にこれの変換命令は AWS-SDK の機能にあるので、これに置き換えた所うまく行きました。
このように「今回修正が必要だった箇所はこの部分」だけで、またこの部分については Node.js が対象の一方で llrt ではこの部分が動かないと言う不具合があった事から、このような結果になったわけで。この問題は「llrtがBeta版じゃなくなったら、この問題はなくなる」のかと思います。
総括
いやあ「とにかくすごい」って思ったわけで、筆者が作った「しょぼいフレームワーク」の中身を「理解・把握」してくれ、それを元に普通に動作できるプログラムを組んでくれるわけで、また「AWS Lambda + LLRT + S3」なので、アクセス数が少ない「社内アプリ」程度なら、かなりローコスト(0円で運用の可能性)もあるわけで、たとえば「出勤・退勤管理Webアプリ」程度だと、普通に作れそうです。
あと「HTML画面などのデザイン」も「普通によく見るような手作り感があんまり無い」レベルで、あと「LLRT=AWS Lambda で超高速実行」なので「実行感も違和感が全く無い」ので、非常に「AIコーディングって使える」なあって実感した次第です。
それと以前に書いた記事
において「やっぱり以前思った事」これは変わらないが、開発効率ってのは「AI=claudeCodeなど」を利用する事で「開発を行う人数」が減らせる事はできるかもなあって思った次第だし、社会アプリ的なものなら、非エンジニアでも「ほぼノーコードで作れる未来」ってのは「もう来てるなあ」って思いました。
以上長々とでしたが、同じ感じの「感動」を見てもらった人たちが共感していただけたら幸いです。



