At least, as far as I can see, Twit.el is effectively dead, and has been since the move to Open Auth. It had some great features, and it was a great project. So thanks to TherionTlax?, H Durer, DaveKerschner Ian Eure, and any other contributors. --JonathanArkell

If an enterprising developer wanted to make it live again, all they would need to do is change the auth scheme. might be a good place to start.



Twit.el is a wrapper library for, and a reasonably functional client. You can post tweets, follow your friends tweets, list your friends and your followers, perform searches, retrieve @msgs and direct messages, and even use multiple accounts.

Twit.el has a novel updating mechanism that works with AutoInstall: every time twit.el is updated, I post a message with the twit_el account saying as much. You can move your point to the text “twit.el” and hit “i”, which should start the installation process.

It was originally authored by TheronTlax. H Durer, DaveKerschner, and JonathanArkell have also made contributions. Currently Jonathan Arkell is working with it. The most recent version is posted to the wiki. When Jonathan updates twit.el (or any other elisp library), he usually tweets about it, so feel free to follow him ( You can also follow for a low-traffic announce only, when new verions are up.

Additionally if you see something you want to add, or fix, feel free to change it and upload it to the wiki. Just make sure to increment the version number, and mention in the changelog what you did.

Lots of big changes have been happening recently, including: direct tweets (view/send), images, multi-account handling and sophisticated filtering.

Download and install

Save the file to a directory (suggestion: ~/.emacs.d/twit/). Add the following autoload commands to your ~/.emacs InitFile:

(add-to-list 'load-path "~/.emacs.d/twit")  ; Save directory

;; Define M-x commands

(autoload 'twit-show-recent-tweets	"twit" "" t) ; most recent direct tweets (!)
(autoload 'twit-show-at-tweets		"twit" "" t) ; directed to you
(autoload 'twit-show-friends 		"twit" "" t) ; your friends
(autoload 'twit-show-followers 		"twit" "" t) ; your followers

(autoload 'twit-follow-recent-tweets	"twit" "" t) ; at idle, check at background

(autoload 'twit-post			"twit" "" t)
(autoload 'twit-post-region		"twit" "" t)
(autoload 'twit-post-buffer		"twit" "" t)
(autoload 'twit-direct			"twit" "" t) ; tweet to person

(autoload 'twit-add-favorite		"twit" "" t) ; Add to favourite: (*) star
(autoload 'twit-remove-favorite 	"twit" "" t)

(autoload 'twit-add-friend  		"twit" "" t) ; follow a friend
(autoload 'twit-remove-friend 		"twit" "" t) ; emove a frienda

;; Customize twit-multi-accounts in order to use these: ((user . pass) ...)
(autoload 'twit-switch-account 		"twit" "" t)
(autoload 'twit-direct-with-account  	"twit" "" t)
(autoload 'twit-post-with-account 	"twit" "" t)

(autoload 'twit-show-direct-tweets-with-account "twit" "" t)
(autoload 'twit-show-at-tweets-with-account 	"twit" "" t)


(setq twit-user "nick")
(setq twit-pass "pass")

;; Key bindings examples
;; Requires that autoloads above have been added to ~/.emacs

(global-set-key "\C-cTT"  'twit-follow-recent-tweets) ; (s)how (T)weets
(global-set-key "\C-cTst" 'twit-follow-recent-tweets) ; (s)how (t)weets
(global-set-key "\C-cTsa" 'twit-show-at-tweets)       ; (s)how (a)t
(global-set-key "\C-cTsf" 'twit-show-at-tweets)       ; (s)how (f)riends
(global-set-key "\C-cTsl" 'twit-show-at-tweets)       ; (s)how fo(l)lowers

(global-set-key "\C-cTpp" 'twit-post)		      ; (p)ost
(global-set-key "\C-cTpr" 'twit-post-region)	      ; (p)post (r)egion
(global-set-key "\C-cTpb" 'twit-post-buffer)	      ; (p)post (b)uffer
(global-set-key "\C-cTpr" 'twit-direct)		      ; (p)post (d)irect
(global-set-key "\C-cTfa" 'twit-add-favorite)	      ; (f)avorite (a)dd
(global-set-key "\C-cTfr" 'twit-remove-favorite)      ; (f)avorite (r)emove


Make sure you customize the twit group, there are some interesting options there.


M-x twit-post RET will prompt for you to type your post directly in the minibuffer.

M-x twit-post-region RET will post the region and

M-x twit-post-buffer RET will post the entire contents of the current buffer.

M-x twit-direct RET will prompt you for a person to tweet to, and a message.

Showing and Following

Any time tweets are shown in a buffer, whether they are direct, @tweets, or part of the normal timeline, the buffer has a custom keymap with the following commands available:

Set the customizable vars twit-show-user-images and twit-user-image-dir to show user images.

You can filter the tweets that are displayed for showing and following tweets. With the custom variable twit-filter-tweets-regex you can remove any tweets that contain a particular regex string. I used that to filter any hashtag tweets for awhile.

if you set twit-filter-at-tweets to true, twit.el will filter out any @tweets that are not directed to you, or your friends.

If you are as annoyed as I am by twitter diarrhea (when a user posts more then 3 consecutive tweets) you can filter it out, by setting twit-filter-diarrhea. It’s value is an integer which is the number of tweets before filtering takes effect. (3 is a good number)

M-x twit-show-recent-tweets RET will create a new buffer and show your most recent messages in it.

M-x twit-follow-recent-tweets RET will check your recent tweets in the background, approximately every 90 seconds. (This is set by the customizable variable twit-follow-idle-interval). If a twitter rate limit is in effect, the time between updates is increased to something reasonable.

With the twit-new-tweet-hook, you can call a function when there is a new unseen tweet. If you use ToDoChiKu you can add the function twit-todochiku to the twit-new-tweet-hook to make a notification pop up.

M-x twit-show-direct-tweets RET Shows you the most recent direct tweets that came your way.

M-x twit-show-at-tweets RET shows you all the tweets directed to you.

M-x twit-show-favorites-tweets RET will create a new buffer and show your favorite tweets in it.

M-x twit-add-favorite RET add a particular tweet to your favorites. You are prompted for the ID of the tweet, and if you are currently on a tweet, it will fill that in as a default.

M-x twit-remove-favorite RET remove a particular tweet from your favorites. As with the previous command, you are prompted for an ID, and the default is the current tweet.

Most twit-show functions accept a numeric prefix argument to show you older tweets in time. So to see page 2 of the tweets, you can hit Ctrl-2 M-x twit-show-recent-tweets RET. If you are on the twit.el buffer, you can just hit Ctrl-2 r.


M-x twit-search RET performs a twit search. Customize the variable twit-completing-searches if you want to add search terms for tab completion.


M-x twit-show-friends RET to list all your friends

M-x twit-show-followers RET to list all your followers

M-x twit-add-friend RET to add and follow a friend.

M-x twit-remove-friend RET to remove a friend


A really great featuer of twit.el is the ability to use multiple twitter accounts with it. First off you need to customize the variable twit-multi-accounts. It is a list of cons cells, with the car being the username, and cdr the password. You should put your main account details in there, as well as your secondary accounts.

M-x twit-switch-account RET to switch accounts to one of your secondary accounts.

M-x twit-direct-with-account RET to send a direct message as a secondary account, and go back to the primary account.

M-x twit-post-with-account RET to post under a secondary account, and go back to the primary.

M-x twit-show-direct-tweets-with-account RET to show direct tweets under an account, and go back to the primary.

M-x twit-show-at-tweets-with-account RET to show any @tweets under an account, and go back to the primary.

I am interested in hearing from other people who use twitter in a multi-account scenario, and would like to hear feature requests!


M-x twit-install-elisp RET if the point is on the name of an emacs lisp package, twit.el will attempt to use auto-install to install that package. Very handy for twit.el updates!

M-x twit-mode RET, if you want to bother, just binds the interactive functions to some keys. Do C-h f RET twit-mode RET for more info.

Upcoming Features


Does anyone have any thoughts on why I can’t see friends pictures as in the screenshots? I think I built emacs with image support, I can certainly look at png and eps files. -IzaakBeekman

Love it! Thanks! Made a small patch to show timestamps of tweets in the local timezone;

Awesmoe! Thanks a lot! I’ve added it to the yet-unreleased 0.16 version. (Update, due it being lost in the shuffle, it never got applied. It is on 0.3 now however) – JonathanArkell

How do other twit.el users feel about not switching focus to the recent tweets window when running twit-show-recent-tweets? Then once you look at the tweets you can just type C-x 1 and get back to work. I noticed this is the behavior for ri-emacs (ruby documentation in Emacs) so I looked at their code and copied their way of doing it. It seems to work properly. Here’s my modified version of twit-show-recent-tweets:

It also doesn’t show in the recent buffer list unless you type C-x o and change to it. If I’m not alone in preferring this behavior I can patch it or you can patch it with my version of the function. – BenAtkin

If you find twit.el asking for a username and password even after customizing one, make sure that your customized settings are loaded before you load twit.el. There is a potential race condition where twit.el requests the customized settings before they are actually set. Maybe twit-post-function should check for this condition every post? – EnigmaCurry

Hmm, I am currently on vacation right now, and it is a little hard to develop and test twit.el at the moment, but I will look at this when I can. You’re very right about the race condition htough. This should be easily fixable. – JonathanArkell

I’m using this client and it works fine, but version 0.0.21 doesn’t show my recent tweets with the default configuration. It looks like there’s a problem with the tweet filter. I’m not an elisp expert, but I made it work by setting twit-filter-tweets-regex to some non-empty value before loading twit.el, e.g:

(setq twit-filter-tweets-regex "^$")

This would filter empty lines so it’s basically a no-op. Of course you can also change twit.el directly and set that value there.

Otherwise it works fine. I’d like to be able to see users’ avatars in the buffer, I wonder if it’s hard to do. – AlbertoGarcia

Fixed! --JA

BUG: There seems to be a serious memory leak. I started a new emacs one evening and loaded twit.el. I then made one post (M-x twit-post RET). Then I invoked twit-follow-recent-tweets. I then left emacs alone. The next morning I found it had a virtual size of 3GB.

I have not investigated further as I do not really know elisp.

Using twit.el version 0.0.21 with GNU Emacs 22.1.1.


Verified. I am looking into the problem now. – JonathanArkell

Update: I have NO idea how to deal with this memory leak. Does anyone have any pointers?

I stopped having memory usage issues when i disabled flyspell for twit-mode. I’ve logged up to 3 days running Twit-recent in (Text Font Fill) without any overzealous memory usage – busytoby

How about to add navigational functions to move the cursor to next/previous posts? I made a small script for it. – whym

Forget about it. IanEure's fork below seems to implement the same feature in a more clever way. – whym

I’ve been hacking on twit.el a bit lately, and I’ve set up a GitHub project for it.

Thanks, the navigation feature greatly works for me! It could be perfect if you could merge the latest twit.el into your fork, which is based on ver 0.1. – whym
Most of Ians patches have been applied, the only one that isn’t has to do with tweet layout.

I’m using Aquamacs 1.7. I’ve had to customize the colors and remove various :box’s and :underline’s to get the display to look good on my dark background setup with images. But the big issue is that #hashtags and @usernames aren’t clickable URLs. However if I click on a message in the empty area to the right of the message text for some users, the user page magically opens in the browser. But other users it never does. - McC @geek

Here’s a proposal for a function to get all the followers, not just the maximum 100 that are requested now by twit-show-followers. If someone wants to integrate it into the existing code, you’re welcome to do it. Kind regards, @Borkdude

(defconst twit-all-followers-list-url
  (concat twit-base-url "/statuses/followers.xml?cursor=%s"))

(defun get-all-followers (cursor acc)
  (let* ((userinfo (cadr (twit-parse-xml (format twit-all-followers-list-url cursor) "GET")))
		 (users (xml-get-children (car (xml-get-children userinfo 'users))
		 (next-cursor (third (car (xml-get-children userinfo 'next_cursor)))))
    (if (not (> (string-to-number (or next-cursor "0")) 0)) (concatenate 'list acc users)
      (get-all-followers next-cursor (concatenate 'list acc users)))))

(defun twit-show-all-followers ()
  "Display a list of all your followers' names."
	(twit-write-title "Followers\n")
	(loop for name in
		  (loop for name in
				(loop for user in
					  (get-all-followers "-1" nil)
					  collect (eighth user))
				collect (third name))
		  for i upfrom 1
		  do (insert (propertize (format "%s\n" name)
								 (if (= 0 (% i 2))
								 'twit-user name))))))

I just added support for new style retweets. I also made a git repo (link above). I’d strongly suggest we start using git instead of manual version tracking on the wiki. Manual version control is just painful. – DaveKerschner

BUG - concat: Symbol’s value as variable is void: image-load-path

FEATURE REQUESTS: I’m not a developer or anything, so I can’t apply the following by myself. Tried out TwIt this evening and stumbled across some problems when using an url shortener: (with 157 chars in the minibuffer) This is just Text to show what I mean This is just Text to show what I mean This is just Text to show what I mean out from here til end)it-el/tree/master If I shorten the tweet to fit into the 140 chars, it uses a link shortener. Would it be possible to shorten links and THEN check for the length of the tweet?

Default zebra striping methods should look good on any arbitrary background colour. Current default zebra stripes look terrible on an otherwise black/dark background. – busytoby

I found a few minor issues with twit-key-list: q is mapped to ‘burry-buffer’; r is mapped to reply while the help says it is mapped to both reload and reply. – glucas

Does it work with yet? (eg.

Well, merely substituting the API references from Twitter with those of Identica, I could use Twit.el for Identica with no issues. Probably means we should think about integrating the Identica feature?

Zebra striping should look a LOT better now. r keybinding is fixed in v3.3. What is wrong with the q binding? --JonathanArkell

I prefer popping up a buffer (like RememberMode) rather than minibuffer when posting, because typing accidentally C-g erases entire input. – rubikitch

I will see about implementing that as a customizable behavior. --JonathanArkell

I am about 60-80% of the way done popup buffer posting. I still have some work to do though. Probably next version.

Not being able to live without some filling of the text, I hacked together a horrible patch. It looks like this. Figuring out how to have it work well with images displayed is an exercise for the reader :-/

I applied this patch. When Twit-recent buffer is not in current window, variable “fill-column” set wrong number. So I fix it. – peccu

Here is such method to use for images posting: twitpic.el --VyazovoiPavel

What about something for “following” direct tweets?

It seems that pictures of twitter users can have different sizes (though most of them are about 75x75). Is there a way to resize the pictures and display them with a standard size? Inconsistent image sizes make the buffer harder to read. – BaoqiuCui

I’d like to have a key binding (e.g. “o”) in twit-status-mode-map to open the first URL in the current tweet if there is one. This is similar to “v” (twit-visit-link) but the cursor does not have to be on the URL link: as long as the cursor is somewhere at the current tweet, it should be fine. If there are more than one URLs in the tweet, just open the first one. If there is no URL in the tweet, do nothing. This key can save a lot of cursor movement if a lot of tweets contain URLs. – BaoqiuCui

Just wrote a quick function to demonstrate what I would like to do with key binding “o”. Hopefully this function can be enhanced and put into twit.el:

(defun bcui-twit-open-link ()
  "Open first URL in current tweet if it exists."
  (when (save-excursion
	  (looking-at ".+http://"))
    (search-forward "http://")

(define-key twit-status-mode-map "o" 'bcui-twit-open-link)


I just added a function called twit-open-link to twit.el (and bumped the version number to 0.3.6). The version I put in is different from the above quick & dirty bcui-twit-open-link. Please let me know if you have any suggestions/questions. – BaoqiuCui

Can we get this code in a version control system somewhere? I have a few changes to make, which will take a few days. In the meantime, someone might come along and upload a new version and I’d have to manually merge changes. No fun.

I’ve fixed a small (very small) bug and would like to add two things:

  • Resize images to specified size
  • Change twit-request-headers to a defcustom so I can hack it in ~/.emacs
  • Finish the popup status writing buffer. I hate writing in the minibuffer.

1. I found a bug in version of “;; Time-stamp: <2007-03-19 18:33:17 thorne>”, line 1674,”(cancel-timer ‘twit-timer)” should be “(cancel-timer twit-timer)”.

2. can you add a function which can set api host, because people in some country can not access

3x. – ahei

The compress-url function doesn’t work in 0.3.12; I believe (substring returned-request url-idx -1) should instead read (substring returned-request url-idx nil).


As of today, (2010-08-31), Basic auth is no longer supported. Unless someone adds it twit.el is no longer going to work. From @twitterapi “The time has come. The Twitter API no longer supports basic auth. Please use OAuth for all authenticated requests. ^TS” I’ve moved on to using twittering-mode which has OAuth support, and imho better search result display, so I will not be working on this. – DaveKerschner

Archived Discussion

I don’t personally do the cell phone thing (it sounds irritating), but anyway, they got slashdotted yesterday. I had never heard of them. But it looked cool, so i joined and wrote twit.el. I think i would like to broaden it--generalize it a bit and let users read friend’s posts. I am working on that….

I should mention that i am neither a great elisp (or other) programmer, nor much experienced with wikis, so please forgive any minor blunders.

Also, a note: has a problem (i think it’s some kind of ham-fisted security measure) where semi-colons and plus characters (’;’ and ‘+’) get silently dropped from your post if you post by HTTP. So at the moment you can’t include those characters. Maybe others as well, but those are the ones i know of so far. – TheronTlax

Are you sure you are properly encoding your request entity? If you aren’t doing that, it might explain why + and ; are getting dropped. Btw, I LOVE twit.el.

Thanks! Well, in that case, maybe i ought to, you, know… work on it some. Sigh. So many things to do….

As for being sure i’m encoding the requests properly, well, no, i’m not sure. I did email twitter support and they said it was a known bug on their end. Maybe it’s changed by now. Oy. TheronTlax

I got tired of my Twitter Client crashing on me, so I went ahead and hacked up something to pull out the recent tweets from the friends list. I’ve posted it to the file, and you can use twit-show-recent-tweets to access it. I’d like to see better formatting on my function, and maybe even some font-faces later… but this is a start. – JonathanArkell

Annoying behaviour: Twitit ignores my username and password setting so I have to type it each time I log in. – HenryAtting?

See also